├── .gitignore ├── README.md ├── docs ├── diagram.jpg └── libparser.vpp ├── lib └── eclipse │ ├── eclipse-common │ └── 3.6.200 │ │ └── eclipse-common-3.6.200.jar │ └── eclipse-core │ └── 5.6.0 │ └── eclipse-core-5.6.0.jar ├── license.txt ├── pom.xml └── src ├── main └── java │ └── br │ └── com │ └── criativasoft │ └── cpluslibparser │ ├── HeaderLibraryScanner.java │ ├── LibraryCache.java │ ├── LibraryIndex.java │ ├── LibraryIndexListener.java │ ├── LibraryObjectSerializer.java │ ├── LibraryScanner.java │ ├── LibrarySerializer.java │ ├── SourceParser.java │ ├── metadata │ ├── TAttribute.java │ ├── TClass.java │ ├── TElement.java │ ├── TElementLocation.java │ ├── TError.java │ ├── TFunction.java │ ├── TLibrary.java │ └── TParam.java │ └── utils │ └── ExtFileFilter.java └── test └── java └── nojunit ├── ConsoleLogger.java ├── LogFormatter.java └── RunSourceParser.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | .classpath 3 | .project 4 | .settings/ 5 | 6 | # Intellij 7 | .idea/ 8 | *.iml 9 | *.iws 10 | 11 | # Mac 12 | .DS_Store 13 | 14 | # Maven 15 | log/ 16 | target/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | cplus-libparser 2 | ======== 3 | 4 | Library for metadata extraction (information about classes, methods, variables) of source code in C/C++. 5 | This library uses the Eclipse parser (standalone), and extracts the most relevant information (primarily used to autocomplete). 6 | 7 | The main advantage is that it is entirely in **Java** and no requires native code (like JNI) . 8 | The library makes the scanner in **asynchronous** mode and **multi-thread**, and can make the data parser **in-memory** (from strings) 9 | 10 | This library was created with the main objective to be used in the **Arduino IDE autocomplete system**. 11 | 12 | 13 | Build 14 | ==== 15 | 16 | Use maven to build, the generated jar include the necessary dependencies 17 | > mvn package 18 | 19 | I believe this is a good example of using the CDT Parser outside of Eclipse, because there is almost no information or example of using. 20 | 21 | The code has been optimized to use minimal Eclipse dependencies. 22 | 23 | TIP: You can use the project [eclipse-cdt-standalone-astparser](https://github.com/ricardojlrufino/eclipse-cdt-standalone-astparser) to see a TreeView code of the source code structure, serving for debugging purposes 24 | 25 | *Thank you to everyone who has reported bugs and suggested fixes.* 26 | 27 | Diagram 28 | ==== 29 | 30 | ![Diagram](https://github.com/ricardojlrufino/cplus-libparser/raw/master/docs/diagram.jpg "Diagram") 31 | -------------------------------------------------------------------------------- /docs/diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardojlrufino/cplus-libparser/079df5cebe948976f8da3112e18772a70818375f/docs/diagram.jpg -------------------------------------------------------------------------------- /docs/libparser.vpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardojlrufino/cplus-libparser/079df5cebe948976f8da3112e18772a70818375f/docs/libparser.vpp -------------------------------------------------------------------------------- /lib/eclipse/eclipse-common/3.6.200/eclipse-common-3.6.200.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardojlrufino/cplus-libparser/079df5cebe948976f8da3112e18772a70818375f/lib/eclipse/eclipse-common/3.6.200/eclipse-common-3.6.200.jar -------------------------------------------------------------------------------- /lib/eclipse/eclipse-core/5.6.0/eclipse-core-5.6.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardojlrufino/cplus-libparser/079df5cebe948976f8da3112e18772a70818375f/lib/eclipse/eclipse-core/5.6.0/eclipse-core-5.6.0.jar -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [ This is the first released version of the Lesser GPL. 10 | It also counts as the successor of the GNU Library Public 11 | License, version 2, hence the version number 2.1. ] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | br.com.criativasoft 5 | cplus-libparser 6 | 0.0.1 7 | 8 | 9 | 10 | ossrh 11 | https://oss.sonatype.org/content/repositories/snapshots 12 | 13 | 14 | ossrh 15 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 16 | 17 | 18 | 19 | 20 | 21 | local 22 | file:${basedir}/lib 23 | 24 | 25 | 26 | 27 | 28 | Eclipse Public License - v 1.0 29 | http://www.eclipse.org/legal/epl-v10.html 30 | repo 31 | 32 | 33 | 34 | 35 | 36 | Ricardo JL Rufino 37 | ricardo.jl.rufino@gmail.com 38 | CriativaSoft 39 | http://www.criativasoft.com.br 40 | 41 | 42 | 43 | 44 | 45 | eclipse 46 | eclipse-core 47 | 5.6.0 48 | 49 | 50 | 51 | 52 | eclipse 53 | eclipse-common 54 | 3.6.200 55 | 56 | 57 | 58 | 59 | 60 | 61 | install 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-compiler-plugin 66 | 67 | 1.6 68 | 1.6 69 | 70 | 71 | 72 | 73 | maven-assembly-plugin 74 | 75 | 77 | 78 | jar-with-dependencies 79 | 80 | false 81 | 82 | 83 | 84 | make-assembly 85 | package 86 | 87 | single 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/HeaderLibraryScanner.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser; 18 | 19 | import java.io.File; 20 | 21 | import br.com.criativasoft.cpluslibparser.utils.ExtFileFilter; 22 | 23 | public class HeaderLibraryScanner extends LibraryScanner { 24 | 25 | private File folder; 26 | 27 | public HeaderLibraryScanner(File folder) { 28 | super(); 29 | this.folder = folder; 30 | } 31 | 32 | @Override 33 | protected File[] getFilesToParse( File folder ) { 34 | // check /src directory 35 | File src = new File(folder, "src"); 36 | String name = folder.getName(); 37 | if (src.exists()) { 38 | folder = src; 39 | } 40 | 41 | return folder.listFiles(new ExtFileFilter(".h")); 42 | } 43 | 44 | @Override 45 | protected void configParser( SourceParser parser , File currentFile ) { 46 | // TODO Auto-generated method stub 47 | 48 | } 49 | 50 | @Override 51 | protected String getLibraryName() { 52 | return folder.getName(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/LibraryCache.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser; 18 | 19 | import java.util.HashMap; 20 | import java.util.HashSet; 21 | import java.util.Map; 22 | import java.util.Set; 23 | 24 | import br.com.criativasoft.cpluslibparser.metadata.TAttribute; 25 | import br.com.criativasoft.cpluslibparser.metadata.TClass; 26 | import br.com.criativasoft.cpluslibparser.metadata.TFunction; 27 | import br.com.criativasoft.cpluslibparser.metadata.TLibrary; 28 | 29 | /** 30 | * Metadata cache for one or more libraries, this class can also represent an execution 31 | * context, for example when working with two projects in the workspace. 32 | * @author Ricardo JL Rufino (ricardo@criativasoft.com.br) 33 | * @date 28/11/2014 34 | */ 35 | public class LibraryCache { 36 | 37 | private String name; 38 | 39 | private Set listeners = new HashSet(); 40 | 41 | private Map libraries = new HashMap(); 42 | 43 | /** this map store the classes from all libraries */ 44 | private Map allClasses = new HashMap(); 45 | // TODO: problems with classes of same name... key can be: Libraty_ClassNAME? 46 | 47 | private Set staticAttrs = new HashSet(); 48 | 49 | private Set globalFunctions = new HashSet(); 50 | 51 | public Set getListeners() { 52 | return listeners; 53 | } 54 | 55 | public void setListeners( Set listeners ) { 56 | this.listeners = listeners; 57 | } 58 | 59 | public Map getLibraries() { 60 | return libraries; 61 | } 62 | 63 | public void setLibraries( Map libraries ) { 64 | this.libraries = libraries; 65 | } 66 | 67 | public Map getAllClasses() { 68 | return allClasses; 69 | } 70 | 71 | public void setAllClasses( Map allClasses ) { 72 | this.allClasses = allClasses; 73 | } 74 | 75 | public Set getStaticAttrs() { 76 | return staticAttrs; 77 | } 78 | 79 | public void setStaticAttrs( Set staticAttrs ) { 80 | this.staticAttrs = staticAttrs; 81 | } 82 | 83 | public Set getGlobalFunctions() { 84 | return globalFunctions; 85 | } 86 | 87 | public Set getGlobalFunctions( String name ) { 88 | 89 | Set functions = getGlobalFunctions(); 90 | Set founds = new HashSet(); 91 | 92 | for (TFunction tFunction : functions) { 93 | if (tFunction.name().equals(name)) { 94 | founds.add(tFunction); 95 | } 96 | } 97 | 98 | return founds; 99 | } 100 | 101 | public void setStaticFunctions( Set globalFunctions ) { 102 | this.globalFunctions = globalFunctions; 103 | } 104 | 105 | public boolean addListener( LibraryIndexListener e ) { 106 | return listeners.add(e); 107 | } 108 | 109 | public boolean removeListener( LibraryIndexListener e ) { 110 | return listeners.remove(e); 111 | } 112 | 113 | public TLibrary getLibrary( String name ) { 114 | return libraries.get(name); 115 | } 116 | 117 | public void setName( String name ) { 118 | this.name = name; 119 | } 120 | 121 | public String getName() { 122 | return name; 123 | } 124 | 125 | @Override 126 | public String toString() { 127 | return name; 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/LibraryIndex.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser; 18 | 19 | import java.io.File; 20 | import java.util.Collection; 21 | import java.util.Map; 22 | import java.util.Set; 23 | import java.util.concurrent.ExecutorService; 24 | import java.util.concurrent.Executors; 25 | import java.util.logging.Logger; 26 | 27 | import br.com.criativasoft.cpluslibparser.metadata.TClass; 28 | import br.com.criativasoft.cpluslibparser.metadata.TFunction; 29 | import br.com.criativasoft.cpluslibparser.metadata.TLibrary; 30 | 31 | // TODO: Documentar 32 | // NOTA: Dizer que é assincromo, e da exemplos de registraro listener. 33 | // 34 | public class LibraryIndex { 35 | 36 | private final static Logger LOG = Logger.getLogger(LibraryIndex.class.getName()); 37 | 38 | /** Number of folders/files scan at same time. */ 39 | public static int THREAD_POOL_SIZE = 10; 40 | 41 | private static ExecutorService executor; 42 | 43 | private static LibraryCache globalCache = new LibraryCache(); 44 | 45 | private static LibraryCache contextCache; 46 | 47 | /** TODO: add DOCS */ 48 | private static boolean useContext = false; 49 | 50 | 51 | private static LibraryCache getCache() { 52 | if(useContext) return contextCache; 53 | else return globalCache; 54 | } 55 | 56 | public static Map getLibraries() { 57 | return getCache().getLibraries(); 58 | } 59 | 60 | public static void addLibrary(TLibrary library){ 61 | LibraryCache cache = getCache(); 62 | 63 | Map libraries = cache.getLibraries(); 64 | Map allClasses = cache.getAllClasses(); 65 | Set listeners = cache.getListeners(); 66 | Set globalFunctions = cache.getGlobalFunctions(); 67 | 68 | TLibrary found = libraries.get(library.name()); 69 | 70 | if(found != null && ! found.isReloadable()) return; 71 | 72 | // Merge with existing library (ex: parsing a new file..) 73 | if (found != null && found.isReloadable()) { 74 | found.merge(library); 75 | found.setLastUpdate(System.currentTimeMillis()); 76 | } 77 | 78 | // Add all class to cache. 79 | Set classes = library.getClasses(); 80 | for (TClass tClass : classes) { 81 | String name = tClass.name().toLowerCase(); 82 | if (!allClasses.containsKey(name)) { 83 | allClasses.put(name, tClass); 84 | } 85 | } 86 | 87 | // Add Function's 88 | Set libFunctions = library.getGlobalFunctions(); 89 | globalFunctions.addAll(libFunctions); 90 | 91 | // Find/resolve inheritance 92 | for (TClass tClass : classes) { 93 | if(tClass.getParent() != null && ! tClass.isParentFound()){ 94 | TClass parent = allClasses.get(tClass.getParent().getName()); 95 | if(parent == null) parent = getClass(tClass.getParent().getName()); 96 | if(parent != null){ 97 | tClass.setParent(parent); 98 | tClass.setParentFound(true); 99 | } 100 | } 101 | } 102 | 103 | boolean contains = libraries.containsKey(library.name()); 104 | if(!contains){ 105 | library.setLastUpdate(System.currentTimeMillis()); 106 | libraries.put(library.name(), library); 107 | LOG.info("load: " + library); 108 | }else{ 109 | LOG.info("reload: " + library); 110 | } 111 | 112 | for (LibraryIndexListener listener : listeners) { 113 | if (contains) { 114 | listener.onReloadLibrary(found); 115 | } else { 116 | listener.onLoadLibrary(library); 117 | } 118 | } 119 | 120 | } 121 | 122 | public static void removeLibrary(TLibrary library){ 123 | 124 | LibraryCache cache = getCache(); 125 | Map libraries = cache.getLibraries(); 126 | Map allClasses = cache.getAllClasses(); 127 | Set listeners = cache.getListeners(); 128 | 129 | if(library != null){ 130 | libraries.remove(library); 131 | 132 | Set classes = library.getClasses(); 133 | 134 | allClasses.values().removeAll(classes); 135 | 136 | // Set keySet = allClasses.keySet(); 137 | // for (String key : keySet) { 138 | // TClass current = allClasses.get(key); 139 | // if(classes.contains(current)){ 140 | // allClasses.remove(key); 141 | // } 142 | // } 143 | 144 | for (LibraryIndexListener listener : listeners) { 145 | listener.onUnloadLibrary(library); 146 | } 147 | } 148 | 149 | } 150 | 151 | public static void removeLibrary(String library){ 152 | LibraryCache cache = getCache(); 153 | Map libraries = cache.getLibraries(); 154 | removeLibrary(libraries.get(library)); 155 | } 156 | 157 | 158 | /** 159 | * Remove all cached instances.. 160 | */ 161 | public void clear(){ 162 | 163 | LibraryCache cache = getCache(); 164 | Map libraries = cache.getLibraries(); 165 | Set listeners = cache.getListeners(); 166 | 167 | Collection libraryList = libraries.values(); 168 | for (TLibrary library : libraryList) { 169 | for (LibraryIndexListener listener : listeners) { 170 | listener.onUnloadLibrary(library); 171 | } 172 | } 173 | 174 | libraries.clear(); 175 | cache.getAllClasses().clear(); 176 | cache.getStaticAttrs().clear(); 177 | cache.getGlobalFunctions().clear(); 178 | } 179 | 180 | 181 | public static void scanFolder(File folder, LibraryScanner scanner){ 182 | 183 | getExecutor().execute(new ScanTask(folder, scanner)); 184 | 185 | } 186 | 187 | public static void scanSource(String source, LibraryScanner scanner){ 188 | 189 | getExecutor().execute(new ScanTask(source, scanner)); 190 | 191 | } 192 | 193 | static ExecutorService getExecutor() { 194 | if(executor == null) executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE); 195 | return executor; 196 | } 197 | 198 | public static Map getAllClasses() { 199 | return getCache().getAllClasses(); 200 | } 201 | 202 | public static TClass getClass(String name){ 203 | return getCache().getAllClasses().get(name.toLowerCase()); 204 | } 205 | 206 | public static Set getGlobalFunctions() { 207 | return getCache().getGlobalFunctions(); 208 | } 209 | 210 | public static Set getGlobalFunctions(String name) { 211 | return getCache().getGlobalFunctions(name); 212 | } 213 | 214 | public static TLibrary getLibrary(String name){ 215 | return getCache().getLibrary(name); 216 | } 217 | 218 | 219 | 220 | public static boolean addListener( LibraryIndexListener e ) { 221 | return getCache().addListener(e); 222 | } 223 | 224 | public static boolean removeListener( LibraryIndexListener e ) { 225 | return getCache().removeListener(e); 226 | } 227 | 228 | public static void setUseContext( boolean useContext ) { 229 | LibraryIndex.useContext = useContext; 230 | } 231 | 232 | public static void setContextCache( LibraryCache contextCache ) { 233 | setUseContext(true); 234 | LibraryIndex.contextCache = contextCache; 235 | } 236 | 237 | public static class ScanTask implements Runnable{ 238 | 239 | private String sourceCode; 240 | private File folder; 241 | private LibraryScanner scanner; 242 | 243 | public ScanTask(File folder, LibraryScanner scanner) { 244 | super(); 245 | this.folder = folder; 246 | this.scanner = scanner; 247 | } 248 | 249 | 250 | public ScanTask(String sourceCode, LibraryScanner scanner) { 251 | super(); 252 | this.sourceCode = sourceCode; 253 | this.scanner = scanner; 254 | } 255 | 256 | @Override 257 | public void run() { 258 | TLibrary library = null; 259 | if(folder != null) library = scanner.scan(folder); 260 | if(sourceCode != null) library = scanner.scan(sourceCode); 261 | 262 | if(library != null && library.name() != null && library.name().length() > 1){ 263 | addLibrary(library); 264 | } 265 | } 266 | 267 | } 268 | 269 | } 270 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/LibraryIndexListener.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser; 18 | 19 | import br.com.criativasoft.cpluslibparser.metadata.TLibrary; 20 | 21 | /** 22 | * Listener for watch library index changes. 23 | * @author Ricardo JL Rufino - (ricardo.jl.rufino@gmail.com) 24 | * @date 22/11/2014 25 | */ 26 | public interface LibraryIndexListener { 27 | 28 | void onLoadLibrary( TLibrary library ); 29 | 30 | void onUnloadLibrary( TLibrary library ); 31 | 32 | void onReloadLibrary( TLibrary library ); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/LibraryObjectSerializer.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | 18 | package br.com.criativasoft.cpluslibparser; 19 | 20 | import java.io.BufferedInputStream; 21 | import java.io.BufferedOutputStream; 22 | import java.io.File; 23 | import java.io.FileInputStream; 24 | import java.io.FileOutputStream; 25 | import java.io.IOException; 26 | import java.io.InputStream; 27 | import java.io.ObjectInput; 28 | import java.io.ObjectInputStream; 29 | import java.io.ObjectOutput; 30 | import java.io.ObjectOutputStream; 31 | import java.io.OutputStream; 32 | 33 | import br.com.criativasoft.cpluslibparser.metadata.TLibrary; 34 | 35 | public class LibraryObjectSerializer implements LibrarySerializer { 36 | 37 | @Override 38 | public void serialize( TLibrary library , File file ) throws IOException { 39 | OutputStream stream = new FileOutputStream(file); 40 | OutputStream buffer = new BufferedOutputStream(stream); 41 | ObjectOutput output = new ObjectOutputStream(buffer); 42 | 43 | try { 44 | output.writeObject(library); 45 | } finally { 46 | output.close(); 47 | } 48 | 49 | } 50 | 51 | @Override 52 | public TLibrary deserialize( File file ) throws IOException { 53 | InputStream stream = new FileInputStream(file); 54 | InputStream buffer = new BufferedInputStream(stream); 55 | ObjectInput input = new ObjectInputStream(buffer); 56 | TLibrary library = null; 57 | try { 58 | library = (TLibrary) input.readObject(); 59 | } catch (ClassNotFoundException e) { 60 | e.printStackTrace(); 61 | } finally { 62 | input.close(); 63 | } 64 | return library; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/LibraryScanner.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser; 18 | 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.util.LinkedList; 22 | import java.util.List; 23 | import java.util.concurrent.Semaphore; 24 | import java.util.logging.Logger; 25 | 26 | import br.com.criativasoft.cpluslibparser.metadata.TElementLocation; 27 | import br.com.criativasoft.cpluslibparser.metadata.TLibrary; 28 | 29 | // TODO: DOCS 30 | // NOTA: Informar que ele utiliza : LibraryIndex.getExecutor() eque usa thread's 31 | public abstract class LibraryScanner { 32 | 33 | private final static Logger LOG = Logger.getLogger(LibraryScanner.class.getName()); 34 | 35 | protected abstract File[] getFilesToParse( File folder ); 36 | 37 | protected boolean serialize = true; 38 | protected boolean deserialize = true; 39 | protected String useCacheFile = "lib.index"; 40 | protected LibrarySerializer serializer = new LibraryObjectSerializer(); 41 | 42 | /** 43 | * Configure parser for this file. 44 | * @param parser 45 | */ 46 | protected abstract void configParser( SourceParser parser , File currentFile ); 47 | 48 | protected abstract String getLibraryName(); 49 | 50 | public TLibrary scan( String sourceCode ) { 51 | 52 | SourceParser parser = new SourceParser(); 53 | configParser(parser, null); 54 | parser.parse(sourceCode); 55 | 56 | TLibrary library = new TLibrary(getLibraryName()); 57 | collectMetadata(parser, library); 58 | 59 | return library; 60 | } 61 | 62 | /** 63 | * 64 | * @param folder 65 | * @return 66 | */ 67 | public TLibrary scan( File folder ) { 68 | 69 | if (!folder.exists() || !folder.isDirectory()) throw new IllegalArgumentException("path is not a directory !"); 70 | 71 | if (deserialize) { 72 | File cache = new File(folder, useCacheFile); 73 | if (cache.exists()) { 74 | LOG.info("deserializing : " + cache.getPath()); 75 | try { 76 | return serializer.deserialize(cache); 77 | } catch (IOException e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | } 82 | 83 | File[] files = getFilesToParse(folder); 84 | 85 | Semaphore semaphore = new Semaphore(0); // to Wait all parser 86 | List runningParser = new LinkedList(); 87 | 88 | for (File file : files) { 89 | File sourcefile = file; 90 | 91 | LOG.fine("LibraryScanner :: scanFolder = " + folder + ", file: " + sourcefile.getName()); 92 | 93 | if (sourcefile.exists()) { 94 | SourceParser parser = new SourceParser(); 95 | configParser(parser, sourcefile); 96 | 97 | LibraryIndex.getExecutor().execute(new FileScanTask(parser, semaphore, sourcefile)); 98 | 99 | runningParser.add(parser); 100 | 101 | } 102 | } 103 | 104 | // Wait all parsers/threads to finish 105 | try { 106 | semaphore.acquire(runningParser.size()); 107 | } catch (InterruptedException e) { 108 | e.printStackTrace(); 109 | } 110 | 111 | TLibrary library = collectMetadata(runningParser); 112 | TElementLocation location = new TElementLocation(folder.getPath(), 0, 0); 113 | library.setLocation(location); 114 | 115 | if (library != null && serialize) { 116 | File cache = new File(folder, useCacheFile); 117 | if (cache.exists()) cache.delete(); 118 | try { 119 | serializer.serialize(library, cache); 120 | LOG.fine("LibraryScanner :: serializing..."); 121 | } catch (IOException e) { 122 | e.printStackTrace(); 123 | } 124 | } 125 | 126 | return library; 127 | 128 | } 129 | 130 | /** 131 | * Extracts all metadata collected by the parser and add the library 132 | * @param parsers - each parser is a file. 133 | * @param folder 134 | * @return returns a new instance of TLibrary 135 | */ 136 | protected TLibrary collectMetadata( List parsers ) { 137 | 138 | TLibrary library = new TLibrary(getLibraryName()); 139 | 140 | for (SourceParser sourceParser : parsers) { 141 | collectMetadata(sourceParser, library); 142 | } 143 | 144 | return library; 145 | 146 | } 147 | 148 | protected TLibrary collectMetadata( SourceParser sourceParser , TLibrary library ) { 149 | library.addAllClass(sourceParser.getClasses()); 150 | library.addAllGlobalFunctions(sourceParser.getGlobalFunctions()); 151 | library.addAllGlobalVariables(sourceParser.getGlobalVariables()); 152 | library.setErrors(sourceParser.getErrors()); 153 | return library; 154 | } 155 | 156 | /** 157 | * Sets the serializer. By default is: {@link LibraryObjectSerializer} 158 | * @param serializer 159 | */ 160 | public void setSerializer( LibrarySerializer serializer ) { 161 | this.serializer = serializer; 162 | } 163 | 164 | /** 165 | * @see #setSerialize(boolean) 166 | */ 167 | public void setSerialize( boolean serialize ) { 168 | this.serialize = serialize; 169 | } 170 | 171 | /** 172 | * @see #setSerialize(boolean) 173 | */ 174 | public void setDeserialize( boolean deserialize ) { 175 | this.deserialize = deserialize; 176 | } 177 | 178 | private static final class FileScanTask implements Runnable { 179 | 180 | private Semaphore semaphore; 181 | private SourceParser parser; 182 | private File file; 183 | 184 | public FileScanTask(SourceParser parser, Semaphore semaphore, File file) { 185 | super(); 186 | this.parser = parser; 187 | this.semaphore = semaphore; 188 | this.file = file; 189 | } 190 | 191 | @Override 192 | public void run() { 193 | parser.parse(file); 194 | semaphore.release(); 195 | } 196 | 197 | } 198 | 199 | } 200 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/LibrarySerializer.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser; 18 | 19 | import java.io.File; 20 | import java.io.IOException; 21 | 22 | import br.com.criativasoft.cpluslibparser.metadata.TLibrary; 23 | 24 | public interface LibrarySerializer { 25 | 26 | public void serialize( TLibrary library , File file ) throws IOException; 27 | 28 | public TLibrary deserialize( File file ) throws IOException; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/SourceParser.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser; 18 | 19 | import java.io.File; 20 | import java.util.*; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | import org.eclipse.cdt.core.dom.ast.*; 25 | import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; 26 | import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; 27 | import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel; 28 | import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; 29 | import org.eclipse.cdt.core.index.IIndex; 30 | import org.eclipse.cdt.core.model.ITranslationUnit; 31 | import org.eclipse.cdt.core.parser.*; 32 | import org.eclipse.cdt.internal.core.dom.parser.ASTProblem; 33 | import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition; 34 | import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit; 35 | import org.eclipse.cdt.internal.core.index.EmptyCIndex; 36 | import org.eclipse.cdt.internal.core.parser.scanner.CharArray; 37 | import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent; 38 | import org.eclipse.core.runtime.CoreException; 39 | 40 | import br.com.criativasoft.cpluslibparser.metadata.*; 41 | import br.com.criativasoft.cpluslibparser.metadata.TClass.TClassType; 42 | 43 | 44 | public class SourceParser { 45 | 46 | private final static Logger LOG = Logger.getLogger(LibraryIndex.class.getName()); 47 | 48 | private Set classes = new HashSet(); 49 | 50 | private Set globalFunctions = new HashSet(); 51 | 52 | private Set globalVariables = new HashSet(); 53 | 54 | private Set errors = new HashSet(); 55 | 56 | Map definedMacros = new HashMap(); 57 | 58 | private TClass currentClass; 59 | 60 | boolean hasFunctionsOverload = false; // 2 functions with same name. 61 | 62 | private boolean parseInternalAttrs = false; 63 | 64 | private boolean parseComments = true; 65 | 66 | private static final String STR_VOID = "void"; 67 | private static final String STR_STATIC = "static"; 68 | private static final String STR_EXTERN = "extern"; 69 | 70 | private String defaultFileName = "SourceCode.c"; 71 | 72 | private int options = 0; 73 | 74 | // AST variables... 75 | private IASTCompositeTypeSpecifier curreType; 76 | private IASTNode curretNode; 77 | private ICPPASTVisibilityLabel publicScopeLabel = null; 78 | 79 | public void parse(String sourceCode){ 80 | FileContent fileContent = new InternalFileContent(defaultFileName, new CharArray(sourceCode)); 81 | enableOption(GPPLanguage.OPTION_IS_SOURCE_UNIT); 82 | enableOption(ITranslationUnit.AST_SKIP_ALL_HEADERS); 83 | parse(fileContent); 84 | } 85 | 86 | public void parse(File file ){ 87 | FileContent fileContent = FileContent.createForExternalFileLocation(file.getPath()); 88 | parse(fileContent); 89 | } 90 | 91 | public void parse(FileContent fileContent ){ 92 | 93 | long time = System.currentTimeMillis(); 94 | 95 | enableOption(GPPLanguage.OPTION_NO_IMAGE_LOCATIONS); 96 | // enableOption(GPPLanguage.OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS); 97 | 98 | String[] includePaths = new String[0]; 99 | IScannerInfo info = new ScannerInfo(definedMacros,includePaths); 100 | IParserLogService log = new DefaultLogService(); 101 | IIndex index = EmptyCIndex.INSTANCE; // or can be null 102 | //final IIndexManager indexManager= CCorePlugin.getIndexManager(); 103 | //IIndex index = indexManager.getIndex(fTranslationUnit.getCProject(),IIndexManager.ADD_EXTENSION_FRAGMENTS_EDITOR); 104 | 105 | IncludeFileContentProvider emptyIncludes = IncludeFileContentProvider.getEmptyFilesProvider(); 106 | 107 | try { 108 | // Using: org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser 109 | IASTTranslationUnit translationUnit = GPPLanguage.getDefault().getASTTranslationUnit(fileContent, info, emptyIncludes, index, options , log); 110 | 111 | navigateTree(translationUnit, 1); 112 | 113 | collectMacrosAndComments(translationUnit); 114 | 115 | } catch (CoreException e) { 116 | e.printStackTrace(); 117 | } 118 | 119 | 120 | LOG.fine("Parser Time: [" + (System.currentTimeMillis() - time) + "]"); 121 | 122 | if(LOG.isLoggable(Level.FINER)){ 123 | 124 | LOG.finer("=========== Global ============="); 125 | 126 | Set attributes = globalVariables; 127 | for (TAttribute node : attributes) { 128 | LOG.finer("#"+node); 129 | } 130 | 131 | Set functions = globalFunctions; 132 | for (TFunction tFunction : functions) { 133 | LOG.finer("#"+tFunction); 134 | } 135 | 136 | LOG.finer("=========== Errors ============="); 137 | 138 | for (TError node : errors) { 139 | LOG.finer("#"+node); 140 | } 141 | 142 | 143 | LOG.finer("=========== Classes ============="); 144 | 145 | for (TClass klass : classes) { 146 | LOG.finer(klass.toString()); 147 | LOG.finer("-----------------------"); 148 | 149 | attributes = klass.getAttributes(); 150 | for (TAttribute node : attributes) { 151 | LOG.finer(node.toString()); 152 | } 153 | 154 | functions = klass.getFunctions(); 155 | for (TFunction tFunction : functions) { 156 | LOG.finer(tFunction.toString()); 157 | } 158 | 159 | LOG.finer(""); 160 | } 161 | } 162 | 163 | } 164 | 165 | protected void collectMacrosAndComments(IASTTranslationUnit translationUnit){ 166 | 167 | LOG.finer("Macro Definitions"); 168 | LOG.finer("====================================="); 169 | 170 | IASTPreprocessorMacroDefinition[] macroDefinitions = translationUnit.getMacroDefinitions(); 171 | for (IASTPreprocessorMacroDefinition macro : macroDefinitions) { 172 | 173 | LOG.finer(macro.getClass().getSimpleName() + " -> " + macro); 174 | 175 | if(macro instanceof IASTPreprocessorFunctionStyleMacroDefinition){ 176 | IASTPreprocessorFunctionStyleMacroDefinition fmacro = (IASTPreprocessorFunctionStyleMacroDefinition) macro; 177 | TFunction function = new TFunction(fmacro.getName().getRawSignature()); 178 | function.setStatic(true); 179 | function.setReturnType("undefined"); 180 | setSourceLocation(function, macro); 181 | globalFunctions.add(function); 182 | }else if(macro instanceof IASTPreprocessorObjectStyleMacroDefinition){ 183 | IASTPreprocessorObjectStyleMacroDefinition amacro = (IASTPreprocessorObjectStyleMacroDefinition) macro; 184 | TAttribute attribute = new TAttribute(amacro.getName().getRawSignature()); 185 | attribute.setStatic(true); 186 | attribute.setType("undefined"); 187 | setSourceLocation(attribute, macro); 188 | // globalVariables.add(attribute); 189 | } 190 | 191 | 192 | } 193 | 194 | if(parseComments){ 195 | 196 | IASTComment[] comments = translationUnit.getComments(); 197 | 198 | List elements = new LinkedList(); 199 | elements.addAll(classes); 200 | elements.addAll(globalFunctions); 201 | 202 | for (IASTComment iastComment : comments) { 203 | 204 | if(!iastComment.isBlockComment()) continue; 205 | 206 | String comment = new String(iastComment.getComment()); 207 | 208 | // Ignore header... 209 | if(comment.contains("Copyright") || comment.contains("This library is free software")) continue; 210 | 211 | for (TElement element : elements) { 212 | 213 | if(element.getLocation() == null || element.getLocation().getStartOffset() == 0) continue; 214 | 215 | int offset = element.getLocation().getStartOffset(); 216 | 217 | IASTNodeLocation location = iastComment.getNodeLocations()[0]; 218 | 219 | int diff = offset - (location.getNodeOffset() + location.getNodeLength()); 220 | 221 | if(diff > 0 && diff < 5){ 222 | 223 | LOG.finest("Doc of: " + element.name()); 224 | LOG.finest(comment); 225 | 226 | } 227 | 228 | 229 | } 230 | 231 | } 232 | 233 | } 234 | 235 | } 236 | 237 | protected void navigateTree(IASTNode node, int index) { 238 | 239 | IASTNode[] children = node.getChildren(); 240 | 241 | this.curretNode = node; 242 | 243 | boolean printContents = true; 244 | 245 | if(node instanceof CPPASTTranslationUnit){ 246 | printContents = false; 247 | } 248 | 249 | // Class type declaration... 250 | if(node instanceof IASTCompositeTypeSpecifier){ 251 | 252 | // Its a typedef inside class 253 | if(curreType != null && curreType != node && curreType.contains(node)){ 254 | if(isPublic(node)){ 255 | _debug("> typedef inside class: " + curreType.getName().getRawSignature(), index); 256 | 257 | // process typedef 258 | IASTCompositeTypeSpecifier lastType = curreType; 259 | TClass lastClass = currentClass; 260 | curreType = (IASTCompositeTypeSpecifier) node; 261 | navigateTree(node, index); 262 | 263 | // restore current 264 | curreType = lastType; 265 | currentClass = lastClass; 266 | return; 267 | }else{ // ignore private typedef 268 | return; 269 | } 270 | } 271 | 272 | curreType = (IASTCompositeTypeSpecifier) node; 273 | 274 | publicScopeLabel = null; 275 | findPublicScopeLabel(curreType); 276 | 277 | String name = curreType.getName().getRawSignature(); 278 | 279 | if(name == null || name.trim().length() == 0){ 280 | 281 | // In struct the name has in another structure (is a sibling node IASTSimpleDeclaration). 282 | if(curreType.getKey() == IASTCompositeTypeSpecifier.k_struct){ 283 | if(curreType.getParent() instanceof IASTSimpleDeclaration){ 284 | IASTSimpleDeclaration parentDec = (IASTSimpleDeclaration) curreType.getParent(); 285 | if(parentDec.getDeclarators().length > 0){ 286 | IASTDeclarator parentNameDec = parentDec.getDeclarators()[0]; 287 | name = parentNameDec.getName().toString(); 288 | } 289 | } 290 | } 291 | 292 | if(name == null || name.trim().length() == 0){ 293 | LOG.info("WARN: ClassName Empty ! CurrentLevel ("+index+") File:"+node.getContainingFilename()); 294 | return; 295 | } 296 | 297 | } 298 | 299 | currentClass = new TClass(name); 300 | setSourceLocation(currentClass, node); 301 | 302 | if(curreType.getKey() == IASTCompositeTypeSpecifier.k_struct){ 303 | currentClass.setType(TClassType.STRUCT); 304 | } 305 | 306 | classes.add(currentClass); 307 | } 308 | 309 | // Parent class. 310 | if(node instanceof ICPPASTBaseSpecifier){ 311 | IASTName name = ((ICPPASTBaseSpecifier)node).getName(); 312 | TClass parent = new TClass(name.getRawSignature()); 313 | currentClass.setParent(parent); 314 | } 315 | 316 | String offset = ""; 317 | try { 318 | offset = (node.getSyntax() != null ? " (offset: "+node.getFileLocation().getNodeOffset()+","+ node.getFileLocation().getNodeLength()+")" : ""); 319 | printContents = node.getFileLocation().getNodeLength() < 30; 320 | } catch (ExpansionOverlapsBoundaryException e) { 321 | e.printStackTrace(); 322 | } catch (UnsupportedOperationException e) { 323 | offset = "UnsupportedOperationException"; 324 | } 325 | 326 | if(LOG.isLoggable(Level.FINEST)){ 327 | String content = (printContents ? node.getRawSignature() : node.getRawSignature().subSequence(0, 5)).toString(); 328 | if(content.length() > 0) content = content.replaceAll("\n", " \\ "); 329 | LOG.finest(String.format("%1$"+(index * 2)+ "s", "-") + node.getClass().getSimpleName() + offset + " -> [[ " + content + " ]]"); 330 | } 331 | 332 | 333 | // Enum 334 | if(node instanceof IASTEnumerationSpecifier){ 335 | 336 | IASTEnumerationSpecifier enumspec = (IASTEnumerationSpecifier) node; 337 | 338 | String enumname = enumspec.getName().toString(); 339 | 340 | if(currentClass == null){ 341 | currentClass = new TClass(enumname); 342 | setSourceLocation(currentClass, node); 343 | } 344 | 345 | IASTEnumerator[] enumerators = enumspec.getEnumerators(); 346 | 347 | for (IASTEnumerator iastEnumerator : enumerators) { 348 | String item = iastEnumerator.getName().toString(); 349 | TAttribute attribute = new TAttribute(enumname, item); 350 | attribute.setPublic(true); 351 | attribute.setEnum(true); 352 | currentClass.add(attribute); 353 | } 354 | 355 | return; // ignore navigate in childs childs.. 356 | } 357 | 358 | 359 | if(isFunction(node)){ 360 | 361 | TFunction function = convertToFunction(node); 362 | 363 | if(function == null) return; 364 | 365 | // if not global ! 366 | if(currentClass != null){ 367 | currentClass.add(function); 368 | }else{ 369 | globalFunctions.add(function); 370 | updateCheckOverloadedFunctions(); 371 | } 372 | } 373 | 374 | // Detect Attributes, Variables. 375 | if(node instanceof IASTDeclarator && ! isFunction(node)){ 376 | 377 | IASTNode parent = node.getParent(); 378 | 379 | if(parent instanceof IASTSimpleDeclaration){ 380 | 381 | IASTSimpleDeclaration parentDeclaration = (IASTSimpleDeclaration) parent; 382 | 383 | // is a class attribute. 384 | if(parent.getParent() instanceof IASTCompositeTypeSpecifier){ 385 | 386 | TAttribute attribute = convertToAttr(node); 387 | if(attribute == null) return; 388 | 389 | attribute.setPublic(isPublic(node)); 390 | 391 | _debug("> Class-Variable:" + attribute, index); 392 | 393 | if(attribute.isPublic() || attribute.isStatic() || currentClass.getType() == TClassType.STRUCT || currentClass.getType() == TClassType.ENUM){ 394 | currentClass.add(attribute); 395 | } 396 | 397 | // Body variable (only for .cpp files.) 398 | // or: Extern, Struct 399 | }else { 400 | 401 | // this can be a Struct(name declaration), ignore... this is handled in 'if'(Class type declaration... ) 402 | if(parentDeclaration.getDeclSpecifier() instanceof IASTCompositeTypeSpecifier){ 403 | IASTCompositeTypeSpecifier specifier = (IASTCompositeTypeSpecifier) parentDeclaration.getDeclSpecifier(); 404 | if(specifier.getKey() == IASTCompositeTypeSpecifier.k_struct){ 405 | return; 406 | } 407 | 408 | } 409 | 410 | TAttribute attribute = convertToAttr(node); 411 | if(attribute == null) return; 412 | 413 | // Extern: Relace ClassName 414 | if(attribute.isExtern()){ 415 | replaceClassName(attribute.getType(), attribute.getName()); 416 | return; 417 | } 418 | 419 | if(attribute.name().length() > 2){ // ignore small variables. ex:. for(int i=0) 420 | setSourceLocation(attribute, node); 421 | CPPASTFunctionDefinition findParentDef = findParent(node, CPPASTFunctionDefinition.class); 422 | 423 | // check if inside function def 424 | if(findParentDef != null){ 425 | TFunction findParent = findParentTFunction(node); 426 | if(findParent != null){ 427 | attribute.setLocal(true); 428 | attribute.setPublic(false); 429 | attribute.setParent(findParent); 430 | findParent.addLocalVariable(attribute); 431 | _debug("> Body-Variable:" + attribute, index); 432 | } 433 | }else{ 434 | _debug("> Global-Variable:" + attribute, index); 435 | attribute.setStatic(true); 436 | attribute.setPublic(true); 437 | globalVariables.add(attribute); 438 | } 439 | 440 | } 441 | 442 | } 443 | 444 | } 445 | 446 | } 447 | 448 | if(node instanceof IASTProblem){ 449 | 450 | IASTProblem problem = (IASTProblem) node; 451 | 452 | int pid = problem.getID(); 453 | 454 | String message = ASTProblem.getMessage(pid, null); 455 | 456 | TError error = new TError(message, pid); 457 | setSourceLocation(error, node); 458 | errors.add(error); 459 | 460 | _debug("ERROR: " + message, index); 461 | 462 | } 463 | 464 | // recursive interaction.... 465 | for (IASTNode iastNode : children) { 466 | navigateTree(iastNode, index + 1); 467 | } 468 | 469 | // termination of current class 470 | if(node instanceof IASTCompositeTypeSpecifier || curreType == node){ 471 | curreType = null; 472 | publicScopeLabel = null; 473 | } 474 | } 475 | 476 | 477 | private void replaceClassName(String currentName, String newName){ 478 | for (TClass tClass : classes) { 479 | if(tClass.name().equals(currentName)){ 480 | tClass.setName(newName); 481 | tClass.setType(TClassType.EXTERN); 482 | } 483 | } 484 | } 485 | 486 | private void updateCheckOverloadedFunctions(){ 487 | 488 | if(globalFunctions.size() <= 1) return; 489 | 490 | List names = new ArrayList(); 491 | Set setnames = new HashSet(); 492 | 493 | for (TFunction tFunction : globalFunctions) { 494 | names.add(tFunction.name()); 495 | } 496 | 497 | setnames.addAll(names); 498 | 499 | hasFunctionsOverload = setnames.size() != names.size(); 500 | } 501 | 502 | public boolean isFunction(IASTNode node){ 503 | return (node instanceof IASTFunctionDeclarator); 504 | } 505 | 506 | private TAttribute convertToAttr( IASTNode node ) { 507 | 508 | IASTName name = ((IASTDeclarator) node).getName(); 509 | IASTSimpleDeclaration parentDec = (IASTSimpleDeclaration) node.getParent(); 510 | String signature = parentDec.getDeclSpecifier().getRawSignature(); 511 | String freturn = null; 512 | 513 | if(name.toString().length() == 0) return null; 514 | 515 | if(signature.length() > 0){ 516 | 517 | if(signature.contains(" ")){ // split attr definition (ex: static int attrName) 518 | String[] split = signature.split(" "); 519 | freturn = split[split.length - 1]; 520 | }else{ 521 | freturn = signature; 522 | } 523 | } 524 | 525 | TAttribute attribute = new TAttribute(freturn, name.toString()); 526 | attribute.setStatic(signature.contains(STR_STATIC)); 527 | attribute.setExtern(signature.contains(STR_EXTERN)); 528 | 529 | if(node instanceof IASTArrayDeclarator){ 530 | attribute.setArray(true); 531 | } 532 | 533 | return attribute; 534 | } 535 | 536 | 537 | public TFunction convertToFunction(IASTNode node){ 538 | 539 | IASTFunctionDeclarator functionNode = ((IASTFunctionDeclarator) node); 540 | 541 | String name = functionNode.getName().getRawSignature(); 542 | 543 | if(name != null && name.trim().length() != 0){ 544 | 545 | // Ignore... 546 | if(name.startsWith("~") || name.startsWith("operator")) return null; 547 | 548 | String signatureDec = ""; 549 | String freturn = null; 550 | 551 | if(functionNode.getParent() instanceof IASTSimpleDeclaration){ // parent can be SimpleDeclaration, FunctionDefinition 552 | IASTSimpleDeclaration parent = (IASTSimpleDeclaration) functionNode.getParent(); 553 | signatureDec = parent.getDeclSpecifier().getRawSignature(); 554 | } 555 | if(functionNode.getParent() instanceof IASTFunctionDefinition){ // parent can be SimpleDeclaration, FunctionDefinition 556 | IASTFunctionDefinition parent = (IASTFunctionDefinition) functionNode.getParent(); // parent can be anoter instance 557 | signatureDec = parent.getDeclSpecifier().getRawSignature(); 558 | } 559 | 560 | if(signatureDec.length() > 0){ 561 | if(signatureDec.contains(" ")){ 562 | String[] split = signatureDec.split(" "); 563 | freturn = split[split.length - 1]; 564 | }else{ 565 | freturn = signatureDec; 566 | } 567 | } 568 | 569 | TFunction function = new TFunction(name, currentClass); 570 | function.setPublic(isPublic(node)); 571 | 572 | if(currentClass != null && currentClass.getType() == TClassType.STRUCT) function.setPublic(true); 573 | 574 | function.setStatic(signatureDec.contains(STR_STATIC)); 575 | if(freturn != null && !STR_VOID.equals(freturn)){ 576 | function.setReturnType(freturn); 577 | } 578 | //System.out.println("SGN ->>> " + signatureDec + ", return: " + freturn); 579 | setSourceLocation(function, functionNode.getParent()); 580 | 581 | IASTNode[] fchilds = functionNode.getChildren(); 582 | 583 | for (IASTNode fchildNode : fchilds) { 584 | if( fchildNode instanceof IASTParameterDeclaration){ 585 | IASTParameterDeclaration param = (IASTParameterDeclaration) fchildNode; 586 | IASTDeclSpecifier declSpecifier = param.getDeclSpecifier(); 587 | String type = declSpecifier.getRawSignature(); 588 | if(!STR_VOID.equals(type)){ 589 | function.addParam(type, param.getDeclarator().getRawSignature()); 590 | } 591 | } 592 | } 593 | 594 | return function; 595 | 596 | } 597 | 598 | return null; 599 | } 600 | 601 | private void setSourceLocation(TElement element, IASTNode node){ 602 | TElementLocation location = new TElementLocation(); 603 | location.setPath(node.getContainingFilename()); 604 | IASTNodeLocation[] nodeLocations = node.getNodeLocations(); 605 | if(nodeLocations != null && nodeLocations.length > 0){ 606 | IASTNodeLocation nodeLocation = node.getNodeLocations()[0]; 607 | location.setOffset(nodeLocation.getNodeOffset()); 608 | location.setLength(nodeLocation.getNodeLength()); 609 | } 610 | element.setLocation(location); 611 | 612 | } 613 | 614 | private T findParent( IASTNode current, Class parentClass) { 615 | 616 | IASTNode parent = current.getParent(); 617 | 618 | if(parent == null || IASTTranslationUnit.class.isAssignableFrom(parent.getClass())) return null; // finish. 619 | 620 | if(parentClass.isAssignableFrom(parent.getClass())){ 621 | return (T) parent; 622 | } 623 | 624 | return findParent(parent, parentClass); 625 | 626 | } 627 | 628 | private TFunction findParentTFunction(IASTNode node) { 629 | 630 | CPPASTFunctionDefinition findParent = findParent(node, CPPASTFunctionDefinition.class); 631 | 632 | if(findParent != null){ 633 | String function = findParent.getDeclarator().getName().toString(); 634 | 635 | // TODO: need check currentClass ? (NOTE: currentClass is not cleared !) 636 | for (TFunction tFunction : globalFunctions) { 637 | 638 | if(tFunction.name().equals(function)){ 639 | 640 | // NOTE: can be many with name name !!! 641 | if(hasFunctionsOverload){ // is only for performance 642 | 643 | TFunction converted = convertToFunction(findParent.getDeclarator()); 644 | 645 | if(tFunction.equals(converted)){ // compare name and params types. 646 | return tFunction; 647 | } 648 | 649 | }else{ 650 | return tFunction; 651 | } 652 | 653 | } 654 | } 655 | } 656 | 657 | return null; 658 | 659 | } 660 | 661 | /** 662 | * Finds and saves the position / in which demarcates the public variables 663 | */ 664 | private void findPublicScopeLabel( IASTCompositeTypeSpecifier type ) { 665 | IASTNode[] children = type.getChildren(); 666 | 667 | for (IASTNode iastNode : children) { 668 | if(iastNode instanceof ICPPASTVisibilityLabel){ 669 | if(((ICPPASTVisibilityLabel) iastNode).getVisibility() == ICPPASTVisibilityLabel.v_public){ 670 | publicScopeLabel = (ICPPASTVisibilityLabel) iastNode; 671 | } 672 | } 673 | } 674 | } 675 | 676 | /** 677 | * Check if is public based in the location of 'Node Offset' reative to public label. 678 | * @param current 679 | * @return 680 | */ 681 | private boolean isPublic(IASTNode current){ 682 | 683 | if(curreType == null){ 684 | _debug("is static! no curreType", 1); 685 | return true; // static ! 686 | } 687 | 688 | if(publicScopeLabel == null){ 689 | return false; 690 | } 691 | 692 | if(current.getNodeLocations()[0].getNodeOffset() > publicScopeLabel.getNodeLocations()[0].getNodeOffset()){ 693 | return true; 694 | } 695 | 696 | return false; 697 | } 698 | 699 | private static void _debug(String text, int index){ 700 | if(LOG.isLoggable(Level.FINEST)){ 701 | LOG.finest(str_repeat("-", (index * 2)) + " " + text); 702 | } 703 | } 704 | 705 | 706 | private static String str_repeat(String schar, int length){ 707 | return new String(new char[length]).replace("\0", schar); 708 | } 709 | 710 | public Set getClasses() { 711 | return classes; 712 | } 713 | 714 | public Set getGlobalFunctions() { 715 | return globalFunctions; 716 | } 717 | 718 | public Set getGlobalVariables() { 719 | return globalVariables; 720 | } 721 | 722 | public Set getErrors() { 723 | return errors; 724 | } 725 | 726 | /** 727 | * Must parse internal attributes in body of functions. 728 | * @param parseInternalAttrs 729 | */ 730 | public void setParseInternalAttrs( boolean parseInternalAttrs ) { 731 | this.parseInternalAttrs = parseInternalAttrs; 732 | } 733 | 734 | public boolean isParseInternalAttrs() { 735 | return parseInternalAttrs; 736 | } 737 | 738 | public void setDefaultFileName( String defaultFileName ) { 739 | this.defaultFileName = defaultFileName; 740 | } 741 | 742 | public String addMacro( String key , String value ) { 743 | return definedMacros.put(key, value); 744 | } 745 | 746 | public void enableOption(int option){ 747 | options |= option; 748 | } 749 | 750 | 751 | } 752 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/metadata/TAttribute.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser.metadata; 18 | 19 | 20 | public class TAttribute extends TElement { 21 | 22 | private static final long serialVersionUID = -6969982195267395502L; 23 | 24 | String type; 25 | 26 | private TElement parent; 27 | 28 | boolean isStatic; 29 | boolean isPublic; 30 | boolean isLocal; // Variable of a function. 31 | boolean isArray; 32 | boolean isExtern; 33 | boolean isEnum; 34 | 35 | public TAttribute(String type, String name) { 36 | super(name); 37 | this.type = type; 38 | } 39 | 40 | public TAttribute(String name) { 41 | super(name); 42 | } 43 | 44 | public String getType() { 45 | return type; 46 | } 47 | public void setType( String type ) { 48 | this.type = type; 49 | } 50 | 51 | public boolean isPublic() { 52 | return isPublic; 53 | } 54 | 55 | public boolean isStatic() { 56 | return isStatic; 57 | } 58 | 59 | public void setPublic( boolean isPublic ) { 60 | this.isPublic = isPublic; 61 | } 62 | 63 | public void setStatic( boolean isStatic ) { 64 | this.isStatic = isStatic; 65 | } 66 | 67 | public void setArray( boolean isArray ) { 68 | this.isArray = isArray; 69 | } 70 | 71 | public boolean isArray() { 72 | return isArray; 73 | } 74 | 75 | public void setExtern(boolean isExtern) { 76 | this.isExtern = isExtern; 77 | } 78 | 79 | public boolean isExtern() { 80 | return isExtern; 81 | } 82 | 83 | public void setEnum( boolean isEnum ) { 84 | this.isEnum = isEnum; 85 | } 86 | 87 | public boolean isEnum() { 88 | return isEnum; 89 | } 90 | 91 | /** 92 | * Check if is a local variable of a function 93 | * @return 94 | */ 95 | public boolean isLocal() { 96 | return isLocal; 97 | } 98 | 99 | public void setLocal(boolean isLocal) { 100 | this.isLocal = isLocal; 101 | } 102 | 103 | public void setParent(TElement parent) { 104 | this.parent = parent; 105 | } 106 | 107 | public TElement getParent() { 108 | return parent; 109 | } 110 | 111 | @Override 112 | public int hashCode() { 113 | final int prime = 31; 114 | int result = 1; 115 | result = prime * result + ((name() == null) ? 0 : name().hashCode()); 116 | result = prime * result + ((type == null) ? 0 : type.hashCode()); 117 | return result; 118 | } 119 | 120 | @Override 121 | public boolean equals(Object obj) { 122 | if (this == obj) 123 | return true; 124 | if (obj == null) 125 | return false; 126 | if (getClass() != obj.getClass()) 127 | return false; 128 | TAttribute other = (TAttribute) obj; 129 | if (name() == null) { 130 | if (other.name() != null) 131 | return false; 132 | } else if (!name().equals(other.name())) 133 | return false; 134 | if (type == null) { 135 | if (other.type != null) 136 | return false; 137 | } else if (!type.equals(other.type)) 138 | return false; 139 | return true; 140 | } 141 | 142 | public String getHtmlRepresentation() { 143 | 144 | if(htmlRepresentation == null){ 145 | 146 | StringBuilder sb = new StringBuilder(); 147 | sb.append(name()); 148 | 149 | 150 | if(type != null){ 151 | sb.append(" : ").append(htmlfont(type, C_LIGHT_BLUE)); 152 | } 153 | 154 | if(isStatic && parent == null && getLocation() != null ){ 155 | sb.append(" - (").append(htmlfont(getLocation().getFileName(), C_GRAY)).append(")"); 156 | } 157 | 158 | htmlRepresentation = sb.toString(); 159 | 160 | } 161 | 162 | return htmlRepresentation; 163 | } 164 | 165 | 166 | @Override 167 | public String toString() { 168 | return (isStatic ? "::" : "") + (isPublic ? "+" : "-") + type + " " + name() + (isArray() ? "[]" : ""); 169 | } 170 | 171 | 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/metadata/TClass.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser.metadata; 18 | 19 | import java.util.HashSet; 20 | import java.util.Set; 21 | 22 | public class TClass extends TElement { 23 | 24 | private static final long serialVersionUID = 1941012827449860693L; 25 | 26 | public static enum TClassType{ 27 | CLASS, ENUM, STRUCT, EXTERN 28 | } 29 | 30 | private TLibrary library; 31 | 32 | private TClass parent; 33 | 34 | private boolean parentFound; 35 | 36 | private Set attributes = new HashSet(); 37 | 38 | private Set functions = new HashSet(); 39 | 40 | private TClassType type = TClassType.CLASS; 41 | 42 | 43 | public TClass() { 44 | super(); 45 | } 46 | 47 | public TClass(String name) { 48 | super(name); 49 | } 50 | 51 | public TClass getParent() { 52 | return parent; 53 | } 54 | 55 | public void setParent( TClass parent ) { 56 | this.parent = parent; 57 | } 58 | 59 | public void setType( TClassType type ) { 60 | this.type = type; 61 | } 62 | 63 | public TClassType getType() { 64 | return type; 65 | } 66 | 67 | public void setAttributes( Set attributes ) { 68 | this.attributes = attributes; 69 | } 70 | 71 | public Set getAttributes() { 72 | return attributes; 73 | } 74 | 75 | public void setFunctions( Set functions ) { 76 | this.functions = functions; 77 | } 78 | 79 | public Set getFunctions() { 80 | return getFunctions(false); 81 | } 82 | 83 | public Set getFunctions(boolean inherited) { 84 | 85 | if(inherited && parent != null){ 86 | Set functionsStore = new HashSet(); 87 | return getFunctions(inherited, functionsStore); 88 | } 89 | 90 | return functions; 91 | } 92 | 93 | public Set getFunctions(boolean inherited, Set functionsStore) { 94 | 95 | functionsStore.addAll(this.functions); 96 | 97 | if(inherited && parent != null){ 98 | return parent.getFunctions(true, functionsStore); 99 | } 100 | 101 | return functionsStore; 102 | } 103 | 104 | public TFunction getFunction( String function , boolean inherited) { 105 | Set functions = getFunctions(inherited); 106 | for (TFunction tFunction : functions) { 107 | if(tFunction.name().equals(function)){ 108 | return tFunction; 109 | } 110 | } 111 | 112 | return null; 113 | } 114 | 115 | public boolean add( TAttribute e ) { 116 | return attributes.add(e); 117 | } 118 | 119 | public boolean add( TFunction e ) { 120 | 121 | if(getType() == TClassType.STRUCT) e.setPublic(true); 122 | 123 | return functions.add(e); 124 | } 125 | 126 | public void setLibrary( TLibrary library ) { 127 | this.library = library; 128 | } 129 | public TLibrary getLibrary() { 130 | return library; 131 | } 132 | 133 | public void setParentFound( boolean parentFound ) { 134 | this.parentFound = parentFound; 135 | } 136 | 137 | public boolean isParentFound() { 138 | return parentFound; 139 | } 140 | 141 | 142 | @Override 143 | public String toString() { 144 | return "TClass:" +name + ", parent: " + getParent(); 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/metadata/TElement.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser.metadata; 18 | 19 | import java.io.Serializable; 20 | import java.util.Collection; 21 | 22 | public class TElement implements Serializable { 23 | 24 | private static final long serialVersionUID = -631746841951042333L; 25 | 26 | protected static final String STR_EMPTY = ""; 27 | protected static final String STR_WHITESPACE = " "; 28 | protected static final String STR_STATIC_TOKEN = "::"; 29 | protected static final String STR_DOT_TOKEN = "."; 30 | 31 | protected static final String C_GRAY = "#A0A0A0"; 32 | protected static final String C_LIGHT_BLUE = "#008080"; 33 | 34 | public TElement() { 35 | } 36 | 37 | public TElement(String name) { 38 | super(); 39 | this.name = name; 40 | } 41 | 42 | protected String name; 43 | protected String htmlRepresentation; 44 | 45 | private TElementLocation location; 46 | 47 | public void setName( String name ) { 48 | this.name = name; 49 | } 50 | 51 | public String getName() { 52 | return name; 53 | } 54 | 55 | public String name() { 56 | return name; 57 | } 58 | 59 | public void setLocation( TElementLocation location ) { 60 | this.location = location; 61 | location.setElement(this); 62 | } 63 | 64 | public TElementLocation getLocation() { 65 | return location; 66 | } 67 | 68 | public void setHtmlRepresentation(String htmlRepresentation) { 69 | this.htmlRepresentation = htmlRepresentation; 70 | } 71 | 72 | public String getHtmlRepresentation() { 73 | if(htmlRepresentation == null) return name; 74 | return htmlRepresentation; 75 | } 76 | 77 | protected String htmlfont(String text, String color){ 78 | if(color == null) return text; 79 | return ""+text+""; 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | return this.getClass().getSimpleName() + ":" + this.getName(); 85 | } 86 | 87 | public static boolean isPrimitive(String type){ 88 | 89 | if(type.equals("int") || type.equals("long") || type.equals("float") || type.equals("double") 90 | || type.equals("char") || type.equals("bool") || type.equals("boolean") || type.equals("size_t")){ 91 | return true; 92 | } 93 | 94 | if(type.startsWith("unsigned") || type.startsWith("uint") || type.startsWith("ulong")){ 95 | return true; 96 | } 97 | 98 | return false; 99 | } 100 | 101 | public static boolean contains(int offset, Collection list){ 102 | for (TElement el : list) { 103 | if(el.getLocation() != null && el.getLocation().containsOffset(offset)){ 104 | return true; 105 | } 106 | } 107 | 108 | return false; 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/metadata/TElementLocation.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser.metadata; 18 | 19 | import java.io.File; 20 | import java.io.Serializable; 21 | 22 | public class TElementLocation implements Serializable { 23 | 24 | private static final long serialVersionUID = -5924664891658306100L; 25 | 26 | private String path; 27 | 28 | private int offset; 29 | 30 | private int length; 31 | 32 | private TElement element; 33 | 34 | public TElementLocation() { 35 | } 36 | 37 | public TElementLocation(int offset, int length) { 38 | this(null, offset, length); 39 | } 40 | 41 | public TElementLocation(String path, int offset, int length) { 42 | super(); 43 | this.path = path; 44 | this.offset = offset; 45 | this.length = length; 46 | } 47 | 48 | public void setElement( TElement element ) { 49 | this.element = element; 50 | } 51 | 52 | public TElement getElement() { 53 | return element; 54 | } 55 | 56 | public String getPath() { 57 | return path; 58 | } 59 | 60 | public String getFileName() { 61 | 62 | if(path == null) return null; 63 | 64 | int lastIndexOf = path.lastIndexOf(File.separator); 65 | 66 | return path.substring(lastIndexOf + 1); 67 | } 68 | 69 | public void setPath( String path ) { 70 | this.path = path; 71 | } 72 | 73 | 74 | /** 75 | * Same as {@link #getOffset()} 76 | * @return 77 | */ 78 | public int getStartOffset() { 79 | return offset; 80 | } 81 | 82 | public int getEndOffset() { 83 | return offset + length; 84 | } 85 | 86 | public void setOffset( int offset ) { 87 | this.offset = offset; 88 | } 89 | 90 | public void setLength(int length) { 91 | this.length = length; 92 | } 93 | 94 | public int getLength() { 95 | return length; 96 | } 97 | 98 | public boolean containsOffset(int offs) { 99 | return (offs >= getStartOffset() && offs <= getEndOffset()); 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | return "["+getStartOffset()+", "+getEndOffset()+"]"; 105 | } 106 | 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/metadata/TError.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser.metadata; 18 | 19 | import java.util.Collection; 20 | 21 | public class TError extends TElement { 22 | 23 | /** 24 | * IProblem relates to a valid syntax error in the parser 25 | */ 26 | protected final static int SYNTAX_RELATED = 0x04000000; 27 | 28 | /** 29 | * Syntax error, detected by the parser. 30 | */ 31 | public final static int SYNTAX_ERROR = SYNTAX_RELATED | 0x001; 32 | 33 | /** 34 | * Missing semicolon. 35 | */ 36 | public final static int MISSING_SEMICOLON = SYNTAX_RELATED | 0x002; 37 | 38 | 39 | public final static int COMPILER_ERROR = SYNTAX_RELATED | 0x002; 40 | 41 | private static final long serialVersionUID = 6976836078408066351L; 42 | 43 | private int code; 44 | 45 | public TError(String name, int code) { 46 | super(name); 47 | this.code = code; 48 | } 49 | 50 | public int getCode() { 51 | return code; 52 | } 53 | 54 | /** 55 | * @see {@link TElementLocation#getStartOffset()} 56 | * @return 57 | */ 58 | public int getStartOffset() { 59 | TElementLocation location = getLocation(); 60 | if(location != null) return location.getStartOffset(); 61 | return -1; 62 | } 63 | 64 | /** 65 | * @see {@link TElementLocation#getEndOffset()} 66 | * @return 67 | */ 68 | public int getEndOffset() { 69 | TElementLocation location = getLocation(); 70 | if(location != null) return location.getEndOffset(); 71 | return -1; 72 | } 73 | 74 | /** 75 | * @see {@link TElementLocation#getLength()} 76 | * @return 77 | */ 78 | public int getLength() { 79 | TElementLocation location = getLocation(); 80 | if(location != null) return location.getLength(); 81 | return -1; 82 | } 83 | 84 | /** 85 | * @see {@link TElementLocation#getPath()} 86 | * @return 87 | */ 88 | public String getPath() { 89 | TElementLocation location = getLocation(); 90 | if(location != null) return location.getPath(); 91 | return null; 92 | } 93 | 94 | public static boolean containsError(int offset, Collection errors){ 95 | for (TError error : errors) { 96 | if(error.getLocation() != null && error.getLocation().containsOffset(offset)){ 97 | return true; 98 | } 99 | } 100 | 101 | return false; 102 | } 103 | 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/metadata/TFunction.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser.metadata; 18 | 19 | import java.util.HashSet; 20 | import java.util.LinkedHashSet; 21 | import java.util.Set; 22 | 23 | public class TFunction extends TElement { 24 | 25 | private static final long serialVersionUID = 4220518946527465434L; 26 | 27 | protected static final String STR_EMPTY_PARAM = "()"; 28 | 29 | private boolean isPublic = false; 30 | 31 | private boolean isStatic = false; 32 | 33 | private boolean isConstructor = false; 34 | 35 | private int paramCount = 0; 36 | 37 | private TClass parent; 38 | 39 | private Set params = new LinkedHashSet(); 40 | 41 | private Set localVariables = new HashSet(); // variables defined in body of functions () 42 | 43 | private String returnType; 44 | 45 | public TFunction() { 46 | super(); 47 | } 48 | 49 | public TFunction(String name) { 50 | this(name, null); 51 | } 52 | 53 | public TFunction(String name, TClass parent) { 54 | super(name); 55 | this.parent = parent; 56 | if(parent != null && name.equals(parent.name())){ 57 | this.isConstructor = true; 58 | } 59 | } 60 | 61 | public boolean isPublic() { 62 | return isPublic; 63 | } 64 | 65 | public void setPublic( boolean isPublic ) { 66 | this.isPublic = isPublic; 67 | } 68 | 69 | public boolean isStatic() { 70 | return isStatic; 71 | } 72 | 73 | public void setStatic( boolean isStatic ) { 74 | this.isStatic = isStatic; 75 | } 76 | 77 | public void setParent( TClass parent ) { 78 | this.parent = parent; 79 | } 80 | 81 | public TClass getParent() { 82 | return this.parent; 83 | } 84 | 85 | public boolean isConstructor() { 86 | return isConstructor; 87 | } 88 | 89 | public boolean hasParams() { 90 | return paramCount > 0; 91 | } 92 | 93 | public void addParam(String type, String name){ 94 | addParam(new TParam(type, name)); 95 | } 96 | 97 | public void addParam(TParam param){ 98 | this.paramCount++; 99 | this.params.add(param); 100 | } 101 | 102 | public Set getParams() { 103 | return params; 104 | } 105 | 106 | public int getParamCount() { 107 | return paramCount; 108 | } 109 | 110 | public String toDeclarationString(){ 111 | StringBuilder sb = new StringBuilder(); 112 | sb.append(name()); 113 | sb.append(getParamsAsString()); 114 | return sb.toString(); 115 | } 116 | 117 | public String getHtmlRepresentation() { 118 | 119 | if(htmlRepresentation == null){ 120 | 121 | StringBuilder sb = new StringBuilder(); 122 | sb.append(name()); 123 | 124 | if(!hasParams()){ 125 | sb.append(STR_EMPTY_PARAM); 126 | }else{ 127 | sb.append('('); 128 | for (TAttribute tAttribute : params) { 129 | sb.append(htmlfont(tAttribute.getType(),C_LIGHT_BLUE)); 130 | sb.append(STR_WHITESPACE); 131 | sb.append(tAttribute.name()); 132 | sb.append(','); 133 | } 134 | 135 | sb.deleteCharAt(sb.length() - 1); 136 | sb.append(')'); 137 | 138 | } 139 | 140 | if(getReturnType() != null && getReturnType().length() > 0){ 141 | sb.append(" : ").append(htmlfont(getReturnType(), C_GRAY)); 142 | } 143 | 144 | if(isStatic && parent == null ){ 145 | sb.append(" - (").append(htmlfont(getLocation().getFileName(), C_GRAY)).append(")"); 146 | } 147 | 148 | 149 | htmlRepresentation = sb.toString(); 150 | 151 | } 152 | 153 | return htmlRepresentation; 154 | } 155 | 156 | 157 | 158 | public void setReturnType( String freturn ) { 159 | this.returnType = freturn; 160 | } 161 | 162 | public String getReturnType() { 163 | return returnType; 164 | } 165 | 166 | @Override 167 | public int hashCode() { 168 | final int prime = 31; 169 | int result = 1; 170 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 171 | result = prime * result + ((params == null) ? 0 : params.hashCode()); 172 | return result; 173 | } 174 | 175 | @Override 176 | public boolean equals(Object obj) { 177 | if (this == obj) 178 | return true; 179 | if (obj == null) 180 | return false; 181 | if (getClass() != obj.getClass()) 182 | return false; 183 | TFunction other = (TFunction) obj; 184 | 185 | if(! name().equals(other.name())) return false; 186 | 187 | if (paramCount != other.getParamCount()) return false; 188 | 189 | // Same name and not have param's 190 | if( ! hasParams() && !other.hasParams()) return true; 191 | 192 | Set params2 = other.getParams(); 193 | 194 | for (TAttribute param : params) { 195 | if(params2.contains(param)){ 196 | return false; 197 | } 198 | } 199 | 200 | return true; 201 | } 202 | 203 | public void setLocalVariables(Set localVariables) { 204 | this.localVariables = localVariables; 205 | } 206 | 207 | /** 208 | * Variables defined in body of functions 209 | * @return 210 | */ 211 | public Set getLocalVariables() { 212 | return localVariables; 213 | } 214 | 215 | public void addAllLocalVariables(Set localVariable) { 216 | for (TAttribute tAttribute : localVariable) { 217 | addLocalVariable(tAttribute); 218 | } 219 | } 220 | 221 | public void addLocalVariable(TAttribute localVariable) { 222 | this.localVariables.add(localVariable); 223 | localVariable.setLocal(true); 224 | if(localVariable.getParent() == null) localVariable.setParent(this); 225 | } 226 | 227 | 228 | @Override 229 | public String toString() { 230 | 231 | StringBuilder sb = new StringBuilder(); 232 | 233 | if(isConstructor()){ 234 | return name() + getParamsAsString(); 235 | }else{ 236 | if(getParent() != null) sb.append(getParent().name()); 237 | 238 | sb.append((isStatic ? STR_STATIC_TOKEN : STR_DOT_TOKEN) + toDeclarationString()); 239 | 240 | return sb.toString(); 241 | } 242 | 243 | } 244 | 245 | public String getParamsAsString(){ 246 | 247 | if(!hasParams()) return STR_EMPTY_PARAM; 248 | 249 | StringBuilder sb = new StringBuilder(); 250 | sb.append('('); 251 | for (TAttribute tAttribute : params) { 252 | sb.append(tAttribute.getType()); 253 | sb.append(STR_WHITESPACE); 254 | sb.append(tAttribute.name()); 255 | sb.append(','); 256 | } 257 | 258 | sb.deleteCharAt(sb.length() - 1); 259 | sb.append(')'); 260 | 261 | if(getReturnType() != null && getReturnType().length() > 0){ 262 | sb.append(" : ").append(getReturnType()); 263 | } 264 | 265 | return sb.toString(); 266 | } 267 | 268 | } 269 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/metadata/TLibrary.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser.metadata; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Collection; 21 | import java.util.HashSet; 22 | import java.util.List; 23 | import java.util.Set; 24 | 25 | public class TLibrary extends TElement { 26 | 27 | private static final long serialVersionUID = -5028212828784647520L; 28 | 29 | private Set classes = new HashSet(); 30 | 31 | private Set globalFunctions = new HashSet(); 32 | 33 | private Set globalVariables = new HashSet(); 34 | 35 | private Set errors = new HashSet(); 36 | 37 | private boolean reloadable; 38 | 39 | private long lastUpdate; 40 | 41 | 42 | public TLibrary() { 43 | super(); 44 | } 45 | 46 | public TLibrary(String name) { 47 | super(name); 48 | } 49 | 50 | public Set getClasses() { 51 | return classes; 52 | } 53 | 54 | public boolean addClass( TClass klass ) { 55 | klass.setLibrary(this); 56 | return classes.add(klass); 57 | } 58 | 59 | public void addAllClass( Collection c ) { 60 | for (TClass tClass : c) { 61 | addClass(tClass); 62 | } 63 | } 64 | 65 | public void setGlobalFunctions(Set globalFunctions) { 66 | this.globalFunctions = globalFunctions; 67 | } 68 | 69 | public Set getGlobalFunctions() { 70 | return globalFunctions; 71 | } 72 | 73 | public void setGlobalVariables(Set globalVariables) { 74 | this.globalVariables = globalVariables; 75 | } 76 | 77 | public Set getGlobalVariables() { 78 | return globalVariables; 79 | } 80 | 81 | /** 82 | * Sets the library can be updated after being loaded.
83 | * This is usually used for the libraries that are being constantly edited and must be reloaded. 84 | */ 85 | public void setReloadable( boolean reloadable ) { 86 | this.reloadable = reloadable; 87 | } 88 | 89 | public boolean isReloadable() { 90 | return reloadable; 91 | } 92 | 93 | 94 | public Set getAllMembers(){ 95 | Set elements = new HashSet(); 96 | elements.addAll(classes); 97 | if(globalFunctions != null) elements.addAll(globalFunctions); 98 | if(globalVariables != null) elements.addAll(globalVariables); 99 | return elements; 100 | } 101 | 102 | public TElement findMember(String name){ 103 | Set elements = getAllMembers(); 104 | 105 | for (TElement element : elements) { 106 | if(element.name().equals(name)){ 107 | return element; 108 | } 109 | } 110 | 111 | return null; 112 | } 113 | 114 | public void merge(TLibrary library){ 115 | addAllClass(library.getClasses()); 116 | globalFunctions.addAll(library.getGlobalFunctions()); 117 | globalVariables.addAll(library.getGlobalVariables()); 118 | setErrors(library.getErrors()); // replace errors to clear 119 | } 120 | 121 | 122 | public void addAllGlobalVariables(Set globalVariables) { 123 | this.globalVariables.addAll(globalVariables); 124 | } 125 | 126 | public void addAllGlobalFunctions(Set globalFunctions) { 127 | this.globalFunctions.addAll(globalFunctions); 128 | } 129 | 130 | public void addError(TError error){ 131 | this.errors.add(error); 132 | } 133 | 134 | public void setErrors( Set errors ) { 135 | this.errors = errors; 136 | } 137 | 138 | /** Get parser error's */ 139 | public Set getErrors() { 140 | return errors; 141 | } 142 | 143 | public void clear() { 144 | classes.clear(); 145 | errors.clear(); 146 | globalFunctions.clear(); 147 | globalVariables.clear(); 148 | } 149 | 150 | /** 151 | * Clear metadata associated with this file 152 | * @param path - file path 153 | */ 154 | public void clear(String path) { 155 | List list = new ArrayList(); 156 | list.addAll(classes); 157 | list.addAll(errors); 158 | list.addAll(globalVariables); 159 | list.addAll(globalFunctions); 160 | 161 | for (TElement tElement : list) { 162 | if(tElement.getLocation() != null){ 163 | TElementLocation location = tElement.getLocation(); 164 | if (location != null && location.getPath() != null 165 | && (path.equals(location.getPath()) || path.endsWith(location.getPath()))) { 166 | classes.remove(tElement); 167 | errors.remove(tElement); 168 | globalVariables.remove(tElement); 169 | globalFunctions.remove(tElement); 170 | } 171 | } 172 | } 173 | } 174 | 175 | public void setLastUpdate( long lastUpdate ) { 176 | this.lastUpdate = lastUpdate; 177 | } 178 | 179 | public long getLastUpdate() { 180 | return lastUpdate; 181 | } 182 | 183 | 184 | 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/metadata/TParam.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser.metadata; 18 | 19 | public class TParam extends TAttribute { 20 | 21 | private static final long serialVersionUID = 4707381457606163031L; 22 | 23 | private String allowedValues; 24 | 25 | public TParam(String type, String name) { 26 | super(type, name); 27 | } 28 | 29 | public String getAllowedValues() { 30 | return allowedValues; 31 | } 32 | 33 | public void setAllowedValues( String allowedValues ) { 34 | this.allowedValues = allowedValues; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/br/com/criativasoft/cpluslibparser/utils/ExtFileFilter.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, CriativaSoft, All rights reserved. 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3.0 of the License, or (at your option) any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library. 16 | *******************************************************************************/ 17 | package br.com.criativasoft.cpluslibparser.utils; 18 | 19 | import java.io.File; 20 | import java.io.FileFilter; 21 | 22 | public class ExtFileFilter implements FileFilter{ 23 | 24 | private String ext; 25 | 26 | public ExtFileFilter(String ext) { 27 | super(); 28 | this.ext = ext; 29 | } 30 | 31 | 32 | @Override 33 | public boolean accept( File pathname ) { 34 | return pathname.getName().endsWith(ext); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/nojunit/ConsoleLogger.java: -------------------------------------------------------------------------------- 1 | package nojunit; 2 | 3 | 4 | import java.io.FileDescriptor; 5 | import java.io.FileOutputStream; 6 | import java.io.PrintStream; 7 | import java.util.logging.LogRecord; 8 | import java.util.logging.StreamHandler; 9 | 10 | public class ConsoleLogger extends StreamHandler { 11 | 12 | public ConsoleLogger() { 13 | setOutputStream(new PrintStream(new FileOutputStream(FileDescriptor.out))); 14 | } 15 | 16 | 17 | public void publish(LogRecord record) { 18 | super.publish(record); 19 | flush(); 20 | } 21 | 22 | /** 23 | * Override StreamHandler.close to do a flush but not 24 | * to close the output stream. That is, we do not 25 | * close FileDescriptor.out. 26 | */ 27 | public void close() { 28 | flush(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/nojunit/LogFormatter.java: -------------------------------------------------------------------------------- 1 | package nojunit; 2 | 3 | 4 | import java.io.PrintWriter; 5 | import java.io.StringWriter; 6 | import java.util.Date; 7 | import java.util.logging.Formatter; 8 | import java.util.logging.LogRecord; 9 | 10 | public class LogFormatter extends Formatter { 11 | 12 | public String format; 13 | private final Date dat = new Date(); 14 | 15 | public LogFormatter(String logformat) { 16 | format = logformat; 17 | } 18 | 19 | @Override 20 | public String format(LogRecord record) { 21 | dat.setTime(record.getMillis()); 22 | String source; 23 | if (record.getSourceClassName() != null) { 24 | source = record.getSourceClassName().substring(record.getSourceClassName().lastIndexOf('.') + 1); 25 | if (record.getSourceMethodName() != null) { 26 | source += "." + record.getSourceMethodName(); 27 | } 28 | } else { 29 | source = record.getLoggerName(); 30 | } 31 | String message = formatMessage(record); 32 | String throwable = ""; 33 | if (record.getThrown() != null) { 34 | StringWriter sw = new StringWriter(); 35 | PrintWriter pw = new PrintWriter(sw); 36 | pw.println(); 37 | record.getThrown().printStackTrace(pw); 38 | pw.close(); 39 | throwable = sw.toString(); 40 | } 41 | return String.format(format, 42 | dat, 43 | source, 44 | record.getLoggerName(), 45 | record.getLevel(), 46 | message, 47 | throwable); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/nojunit/RunSourceParser.java: -------------------------------------------------------------------------------- 1 | package nojunit; 2 | import java.io.File; 3 | import java.util.Enumeration; 4 | import java.util.logging.Handler; 5 | import java.util.logging.Level; 6 | import java.util.logging.LogManager; 7 | import java.util.logging.Logger; 8 | 9 | import br.com.criativasoft.cpluslibparser.SourceParser; 10 | 11 | public class RunSourceParser { 12 | public static void main( String[] args ) { 13 | 14 | Handler consoleHandler = new ConsoleLogger(); 15 | consoleHandler.setLevel(Level.ALL); 16 | consoleHandler.setFormatter(new LogFormatter("%1$tl:%1$tM:%1$tS [%4$7s] %2$s: %5$s%n")); 17 | 18 | Enumeration loggerNames = LogManager.getLogManager().getLoggerNames(); 19 | while (loggerNames.hasMoreElements()) { 20 | String name = (String) loggerNames.nextElement(); 21 | Logger logger = Logger.getLogger(name); 22 | logger.setLevel(consoleHandler.getLevel()); 23 | for(Handler handler : logger.getHandlers()) { 24 | logger.removeHandler(handler); 25 | } 26 | logger.addHandler(consoleHandler); 27 | } 28 | 29 | 30 | // new SourceParser().parse(new File("/media/Dados/Codigos/Java/Projetos/OpenDevice/opendevice-hardware-libraries/arduino/OpenDevice/DeviceConnection.h")); 31 | // new SourceParser().parse(new File("/media/Dados/Codigos/Java/Projetos/OpenDevice/opendevice-hardware-libraries/arduino/OpenDevice/DeviceManager.h")); 32 | new SourceParser().parse(new File("/media/Dados/Codigos/Java/Projetos/OpenDevice/opendevice-hardware-libraries/arduino/OpenDevice/OpenDevice.h")); 33 | // new SourceParser().parse(new File("/home/ricardo/Documentos/arduino-1.0.6/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino")); 34 | // new SourceParser().parse(new File("/media/Dados/Programacao/arduino-1.5.8/hardware/arduino/avr/cores/arduino/Arduino.h")); 35 | // new SourceParser().parse(new File("/media/Dados/Programacao/arduino-src/hardware/arduino/avr/cores/arduino/HardwareSerial.h")); 36 | // new SourceParser().parse(new File("/media/Dados/Programacao/arduino-1.5.8/hardware/arduino/avr/cores/arduino/USBCore.h")); 37 | } 38 | } 39 | --------------------------------------------------------------------------------