jameskilton / rbgccxml

Ruby library to parse and query C++ header files using GCCXML

This URL has Read+Write access

halostatue (author)
Sat Jan 31 15:32:36 -0800 2009
commit  80d73668c3fc1af0de41a7d19661f9acc116e007
tree    0a7b100bc4803c1cd77c3f6b099a49dc8d839256
parent  f54bc0d2ca7a5fb19bee08ee077f1e210df14df5
name age message
file .gitignore Mon Jul 21 14:18:07 -0700 2008 docuemntation / website update [jameskilton]
file MIT_LICENCE Mon Jul 21 14:18:07 -0700 2008 docuemntation / website update [jameskilton]
file README Loading commit data...
file Rakefile
file TODO Sun Apr 20 15:10:24 -0700 2008 updated todo [jameskilton]
directory lib/
directory samples/ Sun May 04 17:51:05 -0700 2008 example shouldn't expect rubygems automatically... [jameskilton]
directory test/
README
== What is rbgccxml?

RbGCCXML allows one to easily parse out and query C++ code. This library uses GCC-XML to parse out 
the C++ code into XML, and then libxml-ruby for parsing and querying.

GCC-XML (http://www.gccxml.org) is an application that takes takes the parse tree of g++ and 
constructs a very parsable and queryable XML file with all related information. GCC-XML currently 
only works with code declarations; there currently are no plans to support code bodies.

Note: For those familiar with pygccxml, the similarities are minimal. Outside of the purpose
of both libraries, rbgccxml was built from scratch to provide a Ruby-esque query API instead of
being a port. However, many thanks to Roman for his work, without which this library would also
not exist.

== Requirements

* libxml-ruby
* gccxml_gem (binary gem, choose proper platform)

== Installation

  gem install rbgccxml

RbGCCXML will work on all platforms that GCC-XML supports, which is currently all the major platforms
of Linux, Mac and Windows. If you're on a platform for which there isn't a current gccxml_gem build, 
please open a ticket on this project's tracker.
 
== The Project

For bug reports, patch submissions, project annoucements and downloads, visit RbGCCXML's rubyforge
project page at:

http://www.rubyforge.org/projects/rbplusplus

Feel free to post help request, hints, or general ideas on the forums.

RbGCCXML's source is in a git repository hosted on github:

Project page: 

http://github.com/jameskilton/rbgccxml/tree/master

Clone with: 

  git clone git://github.com/jameskilton/rbgccxml.git

== Usage

=== Parsing

The entry point of an RbGCCXML project is as follows:

  # Parse a single header file
  RbGCCXML.parse("/path/to/header/file.h")

  # Parse out all files that match a given glob
  RbGCCXML.parse("/my/headers/**/*.h")

  # Parse out a specified set of files"
  RbGCCXML.parse(["/path/to/file1.h", "/path/to/file2.h", ...])

  # Parse out multiple globs
  RbGCCXML.parse(["/my/headers/**/*.h", "/other/headers/*.hpp"])

=== Configuration

As GCC-XML runs on top of GCC, it will need to know about locations of other header files
that may be included by the header files being parsed out. Adding these directories is very easy.

  RbGCCXML.parse(..., :includes => *directories)

+directories+ can be a single directory string or an array of directories, just like RbGCCXML.parse.

Also, if there are other CXXFLAGS that need to be added to the command line for GCC-XML to properly
parse the source headers, add those via the :cxxflags option.

  RbGCCXML.parse(..., :cxxflags => *flags)

=== Querying By Name

Once the header files have been parsed, RbGCCXML.parse returns a Namespace node that references the 
global namespace of "::". From here, all the function, class, etc declarations are easily queryable.

  source = RbGCCXML.parse("header.h")  #=> <Namespace ...>

Each major C++ part (class, struct, function, method (class functions), argument (of functions, methods, and 
constructors) have a related query method that can be called in one of two ways:

  # Grab all the classes and search from there
  source.classes.find(...)

  # Or just get a class of a given name, or that matches a regex. These calls are the same as
  # source.classes.find(:name => ...)

  # Find all classes with the name "ClassName"
  source.classes("ClassName")  

  # Find all classes that match ...Manager
  source.classes(/Manager$/)

For finding all classes in a namespace:

  source.classes

Or finding all namespaces:

  source.namespaces 

These queries are also infinitely nestable. To find the class "Math" inside the namespace 
"core::utils", you can do:

  source.namespaces("core").namespaces("utils").classes("Math")

or as a short-hand form:

  source.namespaces("core::utils::Math")

=== Querying with #find

Of course, querying for names is only the tip of the powerful querying that RbGCCXML supports.

What if you wanted to find all methods on a class that return an int value and have three arguments?
This is easy with RbGCCXML:

  source.classes("yourclass").methods.find(:returns => :int, :arguments => [nil, nil, nil])

The keys +returns+ and +arguments+ can be used on their own, or together as seen above. 
The +arguments+ option must be an array, and if the type of the argument doesn't matter, placing
'nil' in it's place acts as a wildcard. QueryResult#find is also chainable, provided that there
are always more than one result. Otherwise, if there is just one result, only that Node will
be returned and any further chained QueryResult.find methods will fail with "NoMethodError".

For full details on using this method, please see it's documentation at RbGCCXML::QueryResult.

=== The Next Step

To learn more about RbGCCXML, please start looking through the RbGCCXML::Node class; most of the query
API starts there, and following with that head to RbGCCXML::QueryResult.

== Additional Notes

Querying for unsigned types is currently not implemented.