Saturday, December 24, 2011

Running YouNeedTests on windows xp with visual studio express 2010

Tutorial: running YouNeedTests on windows xp

The problem

I've updated YouNeedTests, my cross-platform tool for extracting and building C++ unit tests embedded in source code comments, to make it usable on Microsoft windows systems too. Here's a basic tutorial on how to set it up and get started on windows.

The tutorial

Installation

YouNeedTests depends on the following tools:
  • Python 3.2 (or newer): get it from the python website.
  • PyYaml: get it from the PyYaml website. I've used version 3.10
  • Mako: get it from the mako templates website. I've installed the latest available version 0.5.0 using Distribute.
  • CMake: get it from the cmake website.
  • YouNeedTests: you can either install git and clone the gitorious repository (this is easy via the installshield of git extensions) or you can head over to the gitorious repository and download the master branch as a tar.gz package (then you will also need a tool like 7-zip to unpack the package).
  • A C++ compiler. Strictly speaking, this is optional, but obviously YouNeedTests won't be very useful without one :) I've installed visual studio 2010 Express edition (free download) from the microsoft website.

Note:the google test framework is included in the YouNeedTests tool.

Building and running some tests

YouNeedTests comes with a run.bat script that runs YouNeedTests on some sample testinputs folder.

  • In a first step, run.bat will delete the testoutput folder if it already exists.
  • In a second step, "The "run.bat" will create a testoutput folder with a file called CMakeLists.txt and a series of folders containing automatically generated code (one folder per testsuite). Run.bat is a very short file, and I encourage you to take a look (and correct the paths to your python installation if needed).
  • In a third step, run.bat will change the working directory to the testoutput folder and try to run CMake on it, in order to generate the visual studio solution. CMake also supports many other compilers - run
    cmake --help
    to get an overview of supported environments.

When run.bat has finished, you should find a lot of files in your testoutput folder (imagine having to create all those by yourself to get a feeling for what YouNeedTests could do for you). You want to open the ALL_TESTS.sln file in Visual Studio 2010 Express. Inside the solution you will find different projects.

  • The ALL_BUILD project: build this to build the googletest framework and the tests extracted from the c++ comments.
  • The ALL_TEST project: build this to run all the tests
  • The t1, t2, t3, ... projects: setting one of those as startup project will run only that testsuite. Running a testsuite separately like this allows you to get much more detailed test output. Unfortunately, the console window containing the test results quickly disappears when the test finishes. You may want to run the test executable from a dos window instead so you can inspect the results.

Troubleshooting

If you run the sample tests by building the ALL_TEST project, but you get errors like

Could not find executable C:/development/youneedtests/youneedtests/testoutput/t4Avg/t4Avg
, it means you forgot to build the ALL_BUILD project first. Right-click ALL_BUILD in the solution explorer in visual studio, and click Build.

If you successfully built the ALL_BUILD project, but while running the sample tests included with YouNeedTests all tests fail with a reason like "OTHER FAILURE", it means that the gtest.dll was not found. In that case you should add the

youneedtests\testoutput\googletest\Debug
folder (use the full path as applicable on your sytem) to your PATH (right click
My Computer
, then click
Properties
, click
Advanced
, click
Environment Variables
, and in the
System Variables
group box, add the folder in the
Path
variable.) An alternative would be for YouNeedTests to copy the .dll files into each of the testsuite folders, but I'd rather not do that (the more tests you have, the more copies of gtest.dll are needed).

Monday, December 19, 2011

YouNeedTests: a python3 based C++ unit testing tool

(Image retrieved from http://blog.hinshelwood.com/. According to google image search this image is labeled for reuse. Please let me know if you disagree.)

Unit testing in C++

Perhaps you recognize the following story. You're finished writing C++ code, and now you want to add some unit tests, because it makes the metrics look good. You're using a well-established C++ unit testing framework, like CppUnit. Adding a new test requires manually adding files to the solution, adding seemingly duplicated information in .cpp and .h files (i.e. implementations and declarations) and invoking obscure macros. Or perhaps you copy an existing test file and start editing it to test new stuff. Or worse: you extend an existing test with some extra lines to avoid creating all the boilerplate code over and over again.

However, being a programmer and not a file copier, I would really appreciate if we could use our computer a bit more efficiently to specify tests.

YouNeedTests: Python3's doctest meets fitnesse for C++ code

doctest? fitnesse?

The brilliant thing about python's doctest module is how it extracts tests from comments embedded in the source code. This leads to executable documentation which by its very nature never needs to become outdated. Doctest is typically used to write unit tests: tests written by programmers for programmers, trying to test little bits of code in isolation.

The brilliant thing about fitnesse is how it specifies different test scenarios in table form. Fitnesse is typically used to define acceptance tests: tests written by business and QA people and intended for business and QA people. Acceptance tests usually involve more objects than unit tests.

requirements

I wanted a tool that could be used with C++, and that transforms comments embedded in the C++ code into unit tests. I also wanted a way to specify different test scenarios in table form. Because I prefer python over C++ in matters of text processing, I decided this was an ideal opportunity to wet my feet in several "hot" and "established" technologies:

  • git as source code management system. The brilliant thing about git is its distributed model, its insane flexibility, speed and compactness, and its superb support for branching and merging.
  • python3, the somewhat controversial, non-backward compatible successor to the very popular python2 language. I still have to find out what's so brilliant about python3 - but so far python3 hasn't been a negative experience.
  • yaml to format the comments from which the code will be generated. The brilliant thing about yaml is how it combines expressiveness of XML with a much more human friendly syntax. Human friendly enough that I didn't create a domain specific language to specify tests in.
  • googletest as backend unit testing framework. The brilliant thing about the googletest framework is how it requires fairly little boilerplate code to write simple tests. The second brilliant thing about googletest is that it supports death-tests, i.e. you can check if a piece of code crashes as expected.
  • CMake for the build system. The brilliant thing about CMake is how cross-platform, easy to use and versatile it is as a build system. It also comes with built-in provision for testing (and loads of stuff I haven't discovered yet).
  • mako to generate boiler plate code and build scripts. The brilliant thing about mako templates is their ease of use and the fast speeds with which they are rendered.

Example

Here's a simple comment that will 6 independent tests from a table of scenarios. Not all tests need to have a table, one can also embed raw code if desired. A comment like the above consists of several parts:
  • a testsuite name
  • a testsuite type: for now 3 types are supported:
    • COLUMNBASED: CODE section contains a list of tables. Each line in each table is an independent test.
    • ROWBASED: CODE section contains a list of tables. Each table becomes a test. Each line in a table is one step in the test.
    • RAW: CODE section contains normal C++ code.
  • a LINK section: this specifies which .cpp files should be linked in with the test
  • an INCLUDE section: this specifies which .h files to include in with the test
  • a STUBS section: this can contain arbitrary C++ code to resolve linker errors. Only stub those parts of the code which are not testing. There's no point in testing stubs :)
  • a PRE section: code in the PRE section is executed before anything from the table is execute
  • a POST section: code in the POST section is executed after executing statements from the table, but before executing assertions from the table
  • a CODE section. In case of a COLUMNBASED or ROWBASED test suite, the CODE section contains a list of tables. Each table has a table header that specifies code templates with placeholders $1, $2, .... The placeholders will be filled in with values from the table cells in the same column. Each table has a NULL column (the ~ symbol) which separates the statements on a line from the assertions.
    • The line containing the string 'twovalues' in table 'TABLE1', e.g. will result in the following lines of code being generated: where the double comma (",,") causes the code template to be unrolled. (Of course the system will also generate all the rest of the required boilerplate code and buildscripts, finally leading to this .cpp file (buildscript not shown here): Despite being used with a toy example, the table format already results in quite some space and boiler-plate reduction :)
All the generated tests can be run at once by issuing "make test" in the output folder:
More detailed test results are available by individually running tests:

Proof of concept code!

Got curious? Hop over to Gitorious! LGPL'd proof of concept code - for now I only tried to use it on debian sid amd64.

Friday, December 16, 2011

Application specific software metrics

Image available under creative commons license from http://www.flickr.com/photos/enrevanche/2991963069/

How to make developers like software metrics

The problem

Managers like metrics. Almost every software project of a given size is characterized by metrics. According to wikipedia,

A software metric is a measure of some property of a piece of software or its specifications. <...> The goal is obtaining objective, reproducible and quantifiable measurements, which may have numerous valuable applications in schedule and budget planning, cost estimation, quality assurance testing, software debugging, software performance optimization, and optimal personnel task assignments.

Typical OO software metrics include things like: "lines of code", "number of modules per 1000 lines of code", "number of comments", "McCabe complexity", "Coupling", "Fan-in" or "Fan-out" of classes. The problem many such general metrics is that they describe (aspects of) the state of your software, but they don't tell you how to go about improving something. At most they give vague hints if any at all: I would hope it's clear to experienced developers that adding lines of code is not something to actively strive for, unless you get a bonus for each line of code you write. Does a high fan-in mean high coupling or rather good code reuse? Does a high number of comments automatically imply they are relevant and up-to-date? It could also be a sign that your codebase is so hard to understand that one needs to include half a manual with each line of code?

An alternative

What can be done to make sure that developers like metrics too? In my opinion, we have to carefully craft our metrics so that they fulfill three basic properties:
  • Single number: it should be possible to summarize each metric in a single, meaningful number. For one specific metric, a higher number must always mean a better (worse) result.
  • Concrete action: for each deterioration it must be unambiguously clear how to go about improving it.
  • Automatable: the metrics must be easy (and preferably very cheap) to calculate automatically. Each developer can be warned automatically if he made a metric significantly worse (or rewarded with a positive report if she improved it) after committing changes to the version control system.

You think this sounds like Utopia and probably requires extremely expensive tools? Think again! With minimal efforts one can already attain some very useful application specific metrics.

Examples

Here I list some possible metrics (actually I have implemented all of these and more as a "hobby" project at my day job):

Counting regular expressions

A lot of useful metrics can be built by counting occurrences of regular expressions. Examples:
  • Counting deprecated constructs: While introducing a new framework in a significant piece of software, there will always be a period where your software features a mixture of both old code and new framework code. Count the API calls of the old code. Anyone adding new calls to the old API is warned to use the new API instead.
  • Counting conditions: if you are removing "if (predicate) doSomething;" statements and replacing them with polymorphism, count how often the old predicates are called. Anyone who adds new calls to the predicate can be warned automatically about using the new framework instead.

Monitoring dependencies between projects and coupling between classes

If your software has a layered structure, your will typically have constraints about which projects are allowed to include from which other projects. Count and list all violations by analyzing your include dependencies. I also use include dependencies to get a rough estimation of coupling between classes and impact of adding/removing #includes (by calculating how many extra statements will have to be compiled as a result of the new #include). (Shameless self-plug: you can use my FOSS pycdep tool for this).

Monitoring McCabe complexity

If you add new "if" statements, you can be warned automatically about increased complexity. This can be automated using a tool like sourcemonitor which has command line options that allow you to bypass its GUI and to integrate it in your own flow.

Unit tests

Check the results of your unit tests after each commit. Anyone breaking one or more tests is warned automatically about fixing them.

Using it in real life

Of course, no one is stopping you to add to these basic tools some machinery to run the metrics automatically on every commit, preferably generating incremental results (i.e. the metrics should measure what changed compared to the previous commit, so you get a clear idea of the impact your changes had) generate diffs and distribute over different computers and collect the results using some suitable framework, make the reports available using a web application created in an easy-to-use web application framework.

In my day job I have set up two such systems running in parallel: the first system will send one email a day, summarizing all changes in all metrics compared yesterday's version of the software (or for some metrics also the changes that took place since the start of the new sprint). The comparisons happen by comparing the metrics tool test reports with reference reports. Reference reports have to be updated explicitly (via the web front-end) annotated with a reason and a rating (improvement/deterioration/status quo). All team members get this report so if one did a really good job of cleaning up code, everyone in the team becomes aware of it (and if he did a really lousy job, there might be some social pressure to get it right ;) ). The second system calculates incremental metrics per commit, sends email reports to the committer only, but makes the reports available for interested viewers on the intranet (together with author, commit message and revision number).

Although such system can sound scary (I named it "Big Brother"), in practice we only use it to improve both code and team quality and an anonymous poll showed that without exception, every developer liked it (no one wants to dive into someone else's lousy code :) ) Reports with significant changes (good or bad) are discussed in the team on a daily standup meeting, and can identify misunderstandings about the architecture of the code, or result in ideas for organizing training sessions.

Caution

Relying solely on such metrics can give a false fuzzy feeling of software quality. One only improves what is measured. Code review by experienced team members is a good addition to all of the above.

If you, dear reader, have ideas for other metrics, or remarks about the contents of this or other blog entries, feel free to comment.

Tuesday, November 22, 2011

Semantic diff

The problem

I often have the problem of having to compare two ascii reports containing lots of numbers. The two reports contain almost the same values, but here and there small numerical/text differences may occur.

I'm interested in finding out where the differences are, and in the case of numerical differences, where the biggest difference is.

Until recently I just used a normal diff tool, but then it occurred to me that it should be easy to write what I call a "semantic diff" tool, i.e. a specialized diff tool that better highlights the kind of differences I'm interested in.

Here's an example of what I mean (the tables in real life are much biggger, and hopefully make more sense :) )

Reference table

Actual table

Python2.x code

Since both reports have exactly the same layout, it is quite easy to write such a diff tool in python. I want to highlight changes in text that may occur in the report, as well as color code the magnitude of the numerical differences between the two reports (if any). Here's one way to do it (warning: i've reduced indentation because of space constraints): Here's the mako template:

Result

And finally here's the result, when viewed in a browser. Note that the textual differences are marked in yellow. The numerical differences are marked in a color that varies between blue (smallest difference) to red (biggest difference). Not too bad for what is essentially only a few lines of code.

Monday, September 19, 2011

Generate side-by-side diffs in html using vim

Problem

Given two text files, generate a visually appealing diff between them. Do so in html, so it can be visualized in a web browser.

Some approaches

Searching the web

The internet has a suprisingly little amount of flexible standalone tools to generate html diffs that fullfill all my requirements. My requirements include
  • generate side-by-side diff
  • allow to save to html without user intervention
  • work fast on large files with lots of differences
This overview is by no means meant to be exhaustive:
  • lots of diff tools exist, but to the best of my knowledge none of them can generate html.
  • match-patch doesn't seem to generate the layout i'd like to see.
  • diff2html.py and derived tools won't generate intraline differences.
  • csdiff only works on windows systems (but in all honesty, it's faster to generate diffs than using the VIM approach described in this article, and the generated html is more user friendly because it includes navigation between differences)

Rolling your own

In the past i have rolled my own solution in python, using two different approaches:
  • Using python's difflib. This is by far the easiest solution, but it can be very slow for long files with a lot of differences between the two files under comparison.
  • Using a combination of GNU diff and python's difflib. I used GNU diff to generate a rough diff, then used python difflib to generate the intraline differences. This was a lot faster than using only python's difflib already, but still too slow on very large files with many differences. This approach does have the advantage of being very flexible: this tool can generate both side-by-side and line-by-line differences with or without intra-line differences indicated.

Using vim

The text editor vim has an option to visualize the diff of two files by calling it with the command line option "-d":
gvim -d file1.txt file2.txt
Vim highlights as the intraline difference everything between the common prefix and common suffix of a line. Depending on your needs, this may be too much of an approximation. In recent enough versions of vim, the complete diff can be rendered to html using the command
:TOhtml
This command will create a third buffer containing the html representation. Colors are determined by the active colorscheme. Colorscheme can be changed using the command
:colorscheme <name>
Colorscheme only seems to have the expected effect if you use gvim instead of vim. You can experiment with using "vim" instead of "gvim". The names of possible colorschemes can be found underneath the colors folder in the vim installation folder. By default the following colorschemes were installed on my system:
  • blue
  • darkblue
  • default
  • delek
  • desert
  • elflord
  • evening
  • koehler
  • morning
  • murphy
  • pablo
  • peachpuff
  • ron
  • shine
  • slate
  • torte
  • zellner

Automating the html generation using vim

All of the above consists of steps to perform manually, which is ok if you have to compare two files, but far from ok if you have to diff hundreds of files. So how can it be automated? Luckily vim has a few interesting command line options, one of which is the option "-c". Option "-c" allows you to pass a command that will be executed on startup, after the file(s) are loaded. You can pass more than one "-c" command. The following one-liner will load the files, select a colorscheme, generate the diff, save it as html to a file called diff.html, and close vim:
gvim -d orig.txt modified.txt -c "colorscheme zellner"\
-c TOhtml -c "w! test.html" -c q! -c q! -c q!
Note that if you intend to send a lot of commands to vim, you will want to use the command line option "-s" , which allows you to specify a file with vim commands to be executed after the first file is loaded. so the previous command line then becomes
gvim -d orig.txt modified.txt -s commands.vim
and the contents of commands.vim are:
:colorscheme zellner
:TOhtml
:w! test.html
:q!
:q!
:q!

Generating html fragments to embed in a bigger page

Here's one approach to strip the <html> and <head> tags, and replace the <body> tag with a table. In short, replace the previous commands.vim file with this one:
:colorscheme zellner
:let g:html_use_css=0
:TOhtml
:%g/<body/normal k$dgg
:%s/<body\s*\(bgcolor="[^"]*"\)\s*text=\("[^"]*"\)\s*>/<table \1 cellPadding=0><tr><td><font color=\2>/
:%s#</body>\(.\|\n\)*</html>#\='</font></td></tr></table>'#i
:w! PATH/TO/diff.html
:q!
:q!
:q!
Vim's TOhtml command takes a few options that allow you to influence the html generation. Some examples are listed below. Be sure to check out the vim documentation to find out about other useful options.
  • add
    -c "let g:html_use_css=0"
    to avoid generating css (for using with very old browsers, or to embed in emails);
  • add
    -c "let g:html_dynamic_folds=1"
    to generate html with css that allows dynamic folding of sections in the files (useful for source code)
  • add
    -c "let g:html_number_lines=1"
    to show line numbers
  • add
    -c "let g:html_no_pre=1"
    to wrap long lines instead of having scrollable columns
  • add
    -c "let g:html_use_xhtml=1"
    to generate XHTML instead of HTML
Needless to say, if you (ab)use vim in this way in a multi-user environment you will have to take care of choosing a suitable .html filename (unique name for each user/process) to avoid multithreading problems.

Using vim in server mode

Here's another neat trick in case you want to avoid starting up vim over and over again... You can start vim in server mode, meaning that it can listen to remote commands, as follows
gvim --servername DIFFSERVER
DIFFSERVER is just a name I chose. It's an id that is used to identify the correct vim instance that should receive your commands. After you've started vim in server mode you can start a different console (or keep using the same one...) and send commands to the vim server:
vim --servername DIFFSERVER --remote-send ":e PATH/TO/file1.txt"
vim --servername DIFFSERVER --remote-send ":vert diffsplit PATH/TO/file2.txt"
vim --servername DIFFSERVER --remote-send ":colorscheme zellner"
vim --servername DIFFSERVER --remote-send ":let g:html_use_css=1"
vim --servername DIFFSERVER --remote-send ":TOhtml"
vim --servername DIFFSERVER --remote-send ":w! PATH/TO/diff.html" 
vim --servername DIFFSERVER --remote-send ":q!"
vim --servername DIFFSERVER --remote-send ":q"
For now it seems to work reasonably fast even on large files with many differences (except when you use dynamic folding). Diff to html? Piece of cake! ;)

Sunday, September 4, 2011

Dependency graph visualization

The problem

In the case of real software projects, graphviz will come up with an incredible mess of interconnected nodes, which is nearly impossible to navigate. What can be done ?

Specialized graphviz browser

I serendipitously found the ZGRViewer tool, implemented in JAVA, which has features that are aimed directly at visualizing and browsing large graphviz graphs. The most useful features, for the time being, are only available in the unreleased SVN version though. The currently available version for download is somewhat useful, but I'm really waiting for version 0.9.0 to become available. It looks promising, but it remains to be seen if this will actually let us draw any conclusions from inspecting the graph. (For now, formulating prolog queries is a much more powerful tool to find out interesting facts about the source code under test.)

Different layout engine: circos

Not long after finding ZGRViewer, I found a potentially interesting alternative to graphviz in the form of circos. Circos has an interesting approach to visualizing large data tables (you had better refer to their website for details). It was rather easy to add some functionality in pycdep's prolog template that lets us export a set of dependencies as an adjacency matrix, which can then be visualized using the circos tableviewer utility script. Circos offers a huge amount of customization possibilities, and I haven't exactly delved into them. The drawing on top of this blog post, is the result of running circos with all default options on the STAF/STAX source code that I've been using in previous blog posts about pycdep. I'm certain I haven't even scratched the surface of what is possible with this fascinating tool.

Friday, September 2, 2011

Making a json-rpc request from swi-prolog to some other program.

Picture courtesy of http://vitaminsea.typepad.com/vitaminsea/2007/10/index.html

Posting JSON-RPC requests from a prolog program

This tutorial basically performs the opposite of the previous blog entry. We will make a prolog client that talks to a python JSON-RPC service.

Creating the python server

There are several options to create a python JSON-RPC server. One is getting the jsonrpclib library, another one is using a web application framework with support for JSON-RPC - the easiest to learn and use by far being web2py: just unpack the source code, python web2py.py and you can immediately start. No configuration or additional dependencies needed. In web2py, you click a single button to create a simple application named simple_json_server (or any name you like ;) ), then click one button to edit the controller code and add the following code: And that's it! Now we have a fully functioning json-rpc server living at URL 'http://127.0.0.1:5000/simple_json_server/default/call/jsonrpc'.

Creating the prolog client

Creating the prolog client is just as simple.

Practical issues when using JSON-RPC from prolog

Talking to different JSON-RPC servers may result in receiving different replies for the same question:

  • The ordering of the terms in the json([...]) reply can vary from server to server. Swi-prolog chose to optimize for speed, and doesn't provide any tools to cope with such variations, assuming that the reply from one given server would always return terms in the same order.
  • Servers that serve JSON-RPC 1.1 are allowed to leave out the "jsonrpc"="1.1" from their reply. They can apparantly also can add "error"="null" to indicate that no error occurred. 
So in real-life usage of JSON-RPC we have to deal with varying ordering of fields, and with optional fields. For JSON-RPC requests without nested parameters, I found it beneficial to convert the JSON-RPC reply to an association list first, from which then all fields we're interested in can be retrieved and processed.


One way to go about converting a simple json reply to an association list is as follows: While we're converting the list to a form that makes it suitable to convert into an association list, we can also do some processing, like removing null fields, or converting @true to true and @false to false: From the association list it is now easy to get the values we're interested in, in the order we are interested in receiving them.

Note that failing to configure a correct content type when interacting with the server, will cause your reply to show up as a prolog atom instead of a parsed prolog representation. A bit to my surprise, web2py responded with a content-type "'text/html'; charset=utf-8" instead of the expected "application/json". (Edited to add: this was a bug in web2py version <= 1.98.2 - the development version now will return "application/json; charset=utf-8") To make sure that 'text/html; charset=utf-8' is parsed as a JSON-RPC request, we can make the parser believe that this is a valid JSON-RPC reply: http_json:json_type("'text/html'; charset=utf-8"), or in the case of web2py > 1.98.2: http_json:json_type("application/json; charset=utf-8". Perhaps the swi prolog json parser could be made a little bit smarter to ignore the charset definition (Edited to add: this was solved after a bug report. Should be available in swi-prolog versions > 5.11.26)

Monday, August 29, 2011

easy cross-platform inter process communication (IPC) between your program and swi-prolog

Image available under creative commons license from the Flickr photostream of DailyPic.


The problem

In this tutorial I will show how to set up communication between your program (can be written in any language) and swi-prolog. If you, like me, are using python, you might be tempted to use the python/swi-prolog bridge pySWIP, but it has a major disadvantage: it just doesn't work on 64-bit platforms (yet?). If you use any other language, your mileage may vary: e.g. in JAVA you will often be advised to use a prolog that runs on a JVM.

What is presented here is a slightly different approach, which works beautifully across platforms, operating systems and network boundaries. Moreover, it ensures that your prolog code remains very well separated from your main program's code, which cannot be a bad thing.

This tutorial explains matters from the point of view of talking from a python program to a prolog backend.

Nothing prevents you from talking from a prolog frontend to a python backend. The prolog predicates required to do so are not explained in this tutorial (you can read about it in the manual of swi-prolog, in the part about http/http_client)

Approach


Swi-prolog makes it quite easy to write a web service. Swi-prolog also has built-in support for JSON-RPC. By tying together those two functionalities we can interrogate the prolog backend using JSON-RPC requests.

Details


We want to keep it simple for the sake of clarity so we set out to achieve the following goal: a python program will communicate with prolog to calculate the sum of two numbers.

In order to do this we need two things:

  • a prolog program that implements some functionality in prolog and that also responds to JSON-RPC requests (i.e. a JSON-RPC server)
  • a client program that can talk JSON-RPC with our prolog server, and understands its replies (we will create one in python for the sake of simplicity).


Create a python client


After installing jsonrpclib, communication with a JSON-RPC web service is incredibly easy.


First an object is created that represents the server. Here it is assumed that the prolog JSON-RPC server will be running on localhost, port 5000, and it will respond to JSON-RPC requests at url http://localhost:5000/handle.

Once this server proxy is created, one can call methods on it. Here we ask the server to give back the result of "add(5,6)". The jsonrpclib library will automagically convert this method call into a JSON-RPC request, send it to the web-server, read the reply, unparse it from JSON back to python, and return the result. How's that for cool? ;)

If you use another programming language, you will most likely be able to find some specialized library to work with JSON-RPC.

Creating a prolog JSON-RPC server




The prolog JSON-RPC web service isn't that much harder to understand too.
First we import a bunch of libraries that provide much of the required functionality in creating web services out of the box.

Then we get

This line tells prolog that the predicate handle_rpc will be executed (it implicitly assumes that handle_rpc will take a Request as parameter) whenever someone visits the url handle (as indicated by the root(handle) part of the line). Note: nothing prevents you from handling url handle by a predicate with the same name. I gave them different names here (handle and handle_rpc) to make it more explicit in which ways the parameters of http_handler are used.

The next line
http_json:json_type('application/json-rpc').
tells prolog that 'application/json-rpc' is a valid mime-type for a JSON-RPC request. As it turns out, the built-in JSON-RPC support by default only recognizes mime-types of 'application/jsonrequest' and 'application/json'. 'application/json' is the suggested mime-type adopted by RFC4627. The python client, on the other hand uses 'application/json-rpc'. Luckily the makers of swi-prolog decided to make the http_json:json_type predicate a multifile predicate, meaning that it can be extended outside its original file (in other words: by us, the user of the library). If you don't allow 'application/json-rpc' as a valid mime type on the server, the python client will keep receiving an "500 Internal server error" error.

The lines

configure a web server on port Port. After starting prolog, and consulting your prolog server file, you can start the web server on port 5000 by evaluating the following goal:

This will spawn some threads and immediately return to the console prompt, which opens up possibilities for debugging your web service (read more about these possibilities in the HOWTO part of the swi-prolog documentation).

Then comes the handling of the request:


First the json is extracted from the Request, and read into a variable JSONIn.
The http_read_json predicate is provided by the http/http_json library included with swi-prolog. Next, the JSONIn variable (which is basically a string; a datatype described in a subset of javascript) is parsed into a prolog data type. The json_to_prolog predicate is provided by the http/json_convert library included with swi-prolog. After that we evaluate the contents of PrologIn, and from that create PrologOut. Using the current sample code json_to_prolog won't do anything. It can be used to automatically convert the prolog representation of the json reply into a more "prologic" form. To make this magic possible, one needs to declare json_objects. Using prolog_to_json, PrologOut is converted to a more "JSONic" prolog term again, and then sent back to the client with reply_json. This conversion relies on the same json_object declarations as json_to_prolog. For now I don't fully see the advantages of this process. Please chime in, if you have more insights. prolog_to_json is provided by the http/json_convert library.

The evaluate predicate is one we have to write ourselves. It's where the computations take place that are needed to handle the request (in our case: the addition of two numbers). Here's how the evaluate predicate works:
A json request consists of predefined fields:

  • jsonrpc: A String specifying the version of the JSON-RPC protocol. MUST be exactly "2.0".
  • method: A String containing the name of the method to be invoked. Method names that begin with the word rpc followed by a period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and MUST NOT be used for anything else.
  • params : A Structured value that holds the parameter values to be used during the invocation of the method. This member MAY be omitted.
  • id : An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null and Numbers SHOULD NOT contain fractional parts. The id is sent by the client, and should be sent back with the response so the client knows what query is being answered.


More specifically, if we use our python client, after translation to prolog, we get the following term for PrologIn:

We unify it to extract the parameter values, id, and method:


Note that in its current form, the prolog web service is rather inflexible: it will just know how to do an "add" of two numbers. I'll leave it up to your imagination to see how this can be generalized or abstracted.

A JSON-RPC response also has a predefined format. It contains the following fields:

  • jsonrpc: A String specifying the version of the JSON-RPC protocol. MUST be exactly "2.0".
  • result: This member is REQUIRED on success. This member MUST NOT exist if there was an error invoking the method. The value of this member is determined by the method invoked on the Server.
  • error: This member is REQUIRED on error. This member MUST NOT exist if there was no error triggered during invocation. The value for this member MUST follow some predefined rules (see JSON-RPC specification for details).
  • id : This member is REQUIRED. It MUST be the same as the value of the id member in the Request Object. If there was an error in detecting the id in the Request object (e.g. Parse error/Invalid Request), it MUST be Null.


So we are ready to calculate and formulate our reply:


The MethodName = add just verifies that we really were asked to do an add on two numbers.
The Sum = Param1 + Param2 performs the calculation, and
the PrologOut contains the reply that will be sent back to the client.

Running the programs


The hard work is done. Now we can enjoy the fruits of our labour:
Start a console (dos prompt) and start the prolog server on port 5000:

swipl -f server.pl -g "server(5000)."

Start a second console and run the python program:
python rpc.py

If all went well, running the python program should print:
The result is: 11

To kill the prolog server, you can manually type
halt.
on its console prompt, but you could of course also design an RPC request that tells the interpreter to shut itself down.

Your imagination is the only limiting factor.



Saturday, July 23, 2011

pycdep 0.0.2 released


Image courtesy of eyehook.com

There have been so many improvements and bug fixes that a new release was inevitable.
You can get it here.
Enjoy!

Saturday, July 16, 2011

Screencast showing pycdep usage.

Pycdep looks interesting, but I have no idea how to use it?!


I feel your pain. The usage of mixed languages (python which examines C++ and generates prolog?!) seems a bit daunting at first sight. Let me assure you it is not (of course I would say that :D ).

To prove that you can get some info about your source code without knowing anything about python or prolog, I have made a screencast in which I run pycdep on a C++ program STAF

Some things covered in the screencast:
- running pycdep to generate the prolog database
- examining the logfile for potential problems
- taking a look at the generated prolog file (what kinds of facts does it contain?)
- running prolog queries
- using the natural language interface (experimental)
- saving results of queries to a file

Hope this is interesting to some of you. Note that you may want to watch it on youtubeas it appears wider there, and the fonts are better readable there. To watch the video on YouTube, click the YouTube icon in the bar just underneath the video image or follow this link.



Some technical details: the screencast was made using recordmydesktop on a linux debian unstable desktop. The fonts on the terminal and inside vim were increased to size 18 to have a readable end result. The resulting .ogv file was then transcoded to mpeg2 using ffmpeg (since youtube doesn't support .ogg file format anymore :( ). The end result was a file that was 10 times bigger than the .ogv file (I guess next time I should select a lower bit rate.)

Monday, July 4, 2011

More speedup of pycdep in svn and firefox results


(picture from Patrick Goossens available under CC license.)

A major source of wasted cpu cycles was trying to resolve unresolvable include files over and over again. In the current svn version of pycdep, an unresolvable include file is remembered and before we try to search all paths for an include file, we first check if the include file has already been marked as unresolvable.

The net result of all speed optimizations so far cause an 11x speed-up on the firefox source code (i.e. it now completes in about 82 minutes, whereas before it took 11 hours to generate the dependency database). These 82 minutes are measured on the first run, i.e. before disk accesses are cached.

To give an idea: the firefox source code consists of 134371 files (spread over a lot of folders, also including files like .html, and .js). Of those files, 5527 are header files, and 3338 are cpp files. There's a total of 71936 #include statements. The generated prolog database is 4926271 bytes long. On my mid-end laptop, swi-prolog parses the prolog database in about 0.8 seconds (!). Generating the report included below from the generated prolog database takes about 1.5 minutes.

And because it's fun to see some results of the tool, here's what the tool found:

Some of the things visible in the report generated by pycdep:
  • The file src/content/events/src/nsEventListenerManager.h includes itself (!).
  • The file src/ipc/chromium/src/base/time.h is also shown to include itself, but this is a false positive, caused by instructing pycdep not to include the system library directories. (it contains an #include <time.h>, which would include the system library with that name, but since the system library is not visible to pycdep, it will assume the file tries to include itself).
  • Some of the longer circular dependencies would not readily be detected by reading the source code...
  • 1064 of the header files were found never to be included at all... this makes me wonder why there are there :) Probably this is the result of including some libraries of which only a small part of the functionality is actually used.
  • 23 .cpp files include another .cpp file. The only reason I can think of to include .cpp files in other .cpp files is to work around compiler limitations (e.g. as related to C++ templates, which often require declaration and instantiation to coexist in the same file). I have not yet investigated why firefox needs to include so many .cpp files, but it surely intrigues me.
  • Something not visible in the report, but visible in the log file of the tool is the fact that the firefox source code contains 17994 #include statements that could not be resolved, in part because pycdep was instructed not to take the system libraries into account, and in part probably because of dependencies on third-party libraries not included with the firefox source code.
  • Note about the last entry of the report: "The following files are included more than once by the same file:" This detects only if the same literal #include statement is used twice in a single file. It does not report on depending on the same #include file via different recursive #include paths (which the tool can detect too if wanted, but I didn't ask it to do so for the report included below).

Now, without further delay, here's the report generated by the svn version of pycdep for

changeset: 71680:c1ec764b3cd6
tag: tip
user: Rob Campbell
date: Fri Jun 24 16:00:50 2011 -0300
summary: Bug 663746 - Change Scratchpad shortcut key to something other than F4; r=dao

of the firefox source code. (please let me know if you spot things that do not seem to be correct):

The following circular dependencies are detected:
Strongly connected component: [src/xpcom/string/public/nsPromiseFlatString.h,src/xpcom/string/public/nsDependentString.h,src/xpcom/string/public/nsString.h,src/xpcom/string/public/nsLiteralString.h]
Strongly connected component: [src/xpcom/string/public/nsAString.h,src/xpcom/string/public/nsSubstringTuple.h,src/xpcom/string/public/nsSubstring.h]
Strongly connected component: [src/ipc/chromium/src/base/basictypes.h,src/xpcom/base/nsError.h,src/ipc/chromium/src/base/third_party/nspr/prtypes.h,src/xpcom/base/nscore.h]
Strongly connected component: [src/xpcom/glue/nsISupportsImpl.h,src/xpcom/glue/nsISupportsUtils.h]
Strongly connected component: [src/netwerk/cache/nsDiskCacheStreams.h,src/netwerk/cache/nsDiskCacheBinding.h]
Strongly connected component: [src/other-licenses/atk-1.0/atk/atkgobjectaccessible.h,src/other-licenses/atk-1.0/atk/atk.h]
Strongly connected component: [src/ipc/chromium/src/base/time.h]
Strongly connected component: [src/js/src/jsscopeinlines.h,src/js/src/jsobjinlines.h]
Strongly connected component: [src/js/src/nanojit/avmplus.h,src/js/src/nanojit/njconfig.h]
Strongly connected component: [src/security/nss/lib/util/seccomon.h,src/security/nss/lib/util/secport.h]
Strongly connected component: [src/content/events/src/nsEventListenerManager.h]
Strongly connected component: [src/netwerk/protocol/ftp/nsFtpConnectionThread.h,src/netwerk/protocol/ftp/nsFTPChannel.h]
Strongly connected component: [src/dom/base/nsIDOMScriptObjectFactory.h,src/dom/base/nsIDOMClassInfo.h]
Strongly connected component: [src/js/src/methodjit/CodeGenIncludes.h,src/js/src/methodjit/BaseAssembler.h]
Strongly connected component: [src/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.h,src/content/xul/templates/src/nsXULTemplateResultSetRDF.h,src/content/xul/templates/src/nsXULTemplateResultRDF.h]
Strongly connected component: [src/ipc/chromium/src/base/path_service.h,src/ipc/chromium/src/base/base_paths.h]
Strongly connected component: [src/dom/plugins/ipc/PluginScriptableObjectUtils-inl.h,src/dom/plugins/ipc/PluginScriptableObjectUtils.h]
Strongly connected component: [src/security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.h,src/security/nss/lib/libpkix/pkix/params/pkix_resourcelimits.h,src/security/nss/lib/libpkix/pkix/util/pkix_logger.h,src/security/nss/lib/libpkix/pkix/util/pkix_error.h,src/security/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.h,src/security/nss/lib/libpkix/pkix/top/pkix_validate.h,src/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.h,src/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.h,src/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h,src/security/nss/lib/libpkix/pkix/results/pkix_buildresult.h,src/security/nss/lib/libpkix/pkix/results/pkix_verifynode.h,src/security/nss/lib/libpkix/pkix/util/pkix_list.h,src/security/nss/lib/libpkix/pkix/results/pkix_valresult.h,src/security/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.h,src/security/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.h,src/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.h,src/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.h,src/security/nss/lib/libpkix/pkix/params/pkix_procparams.h,src/security/nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.h,src/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h,src/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.h,src/security/nss/lib/libpkix/pkix/results/pkix_policynode.h,src/security/nss/lib/libpkix/pkix/store/pkix_store.h,src/security/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.h,src/security/nss/lib/libpkix/pkix/util/pkix_tools.h]
Strongly connected component: [src/media/libvorbis/lib/backends.h,src/media/libvorbis/lib/bitrate.h,src/media/libvorbis/lib/psy.h,src/media/libvorbis/lib/codec_internal.h]
Strongly connected component: [src/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.h,src/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h,src/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h,src/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.h,src/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.h,src/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.h,src/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.h,src/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.h,src/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.h,src/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.h,src/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.h,src/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.h,src/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.h,src/security/nss/lib/libpkix/include/pkix_sample_modules.h,src/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.h,src/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h,src/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.h,src/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h]
Strongly connected component: [src/media/libvpx/vp8/common/onyxc_int.h,src/media/libvpx/vp8/common/postproc.h]
Strongly connected component: [src/gfx/harfbuzz/src/hb-object-private.h,src/gfx/harfbuzz/src/hb-private.h]
Strongly connected component: [src/ipc/chromium/src/chrome/common/plugin_messages_internal.h,src/ipc/chromium/src/chrome/common/render_messages_internal.h,src/ipc/chromium/src/chrome/common/worker_messages_internal.h,src/ipc/chromium/src/chrome/common/devtools_messages_internal.h,src/ipc/chromium/src/chrome/common/ipc_message_macros.h,src/ipc/chromium/src/chrome/common/ipc_sync_message_unittest.h]

The following header files are included by no one:
src/accessible/src/atk/nsARIAGridAccessibleWrap.h
src/accessible/src/atk/nsAccessibleRelationWrap.h
src/accessible/src/atk/nsHTMLImageAccessibleWrap.h
src/accessible/src/atk/nsHTMLTableAccessibleWrap.h
src/accessible/src/atk/nsHyperTextAccessibleWrap.h
src/accessible/src/atk/nsTextAccessibleWrap.h
src/accessible/src/atk/nsXULListboxAccessibleWrap.h
src/accessible/src/atk/nsXULMenuAccessibleWrap.h
src/accessible/src/atk/nsXULTreeGridAccessibleWrap.h
src/accessible/src/mac/mozAccessible.h
src/accessible/src/mac/mozAccessibleWrapper.h
src/accessible/src/mac/mozActionElements.h
src/accessible/src/mac/mozDocAccessible.h
src/accessible/src/mac/mozTextAccessible.h
src/accessible/src/mac/nsARIAGridAccessibleWrap.h
src/accessible/src/mac/nsAccessNodeWrap.h
src/accessible/src/mac/nsAccessibleRelationWrap.h
src/accessible/src/mac/nsApplicationAccessibleWrap.h
src/accessible/src/mac/nsDocAccessibleWrap.h
src/accessible/src/mac/nsHTMLImageAccessibleWrap.h
src/accessible/src/mac/nsHTMLTableAccessibleWrap.h
src/accessible/src/mac/nsHyperTextAccessibleWrap.h
src/accessible/src/mac/nsRoleMap.h
src/accessible/src/mac/nsRootAccessibleWrap.h
src/accessible/src/mac/nsTextAccessibleWrap.h
src/accessible/src/mac/nsXULListboxAccessibleWrap.h
src/accessible/src/mac/nsXULMenuAccessibleWrap.h
src/accessible/src/mac/nsXULTreeGridAccessibleWrap.h
src/config/gcc-stl-wrapper.template.h
src/config/gcc_hidden.h
src/config/mkdepend/def.h
src/config/mkdepend/ifparser.h
src/config/mkdepend/imakemdep.h
src/config/msvc-stl-wrapper.template.h
src/config/pathsub.h
src/content/base/public/Element.h
src/content/base/public/FromParser.h
src/content/base/public/nsIDOMGCParticipant.h
src/content/base/public/nsIPrivateDOMImplementation.h
src/content/canvas/public/DocumentRendererChild.h
src/content/canvas/public/DocumentRendererNativeIDChild.h
src/content/canvas/public/DocumentRendererNativeIDParent.h
src/content/canvas/public/DocumentRendererParent.h
src/content/canvas/public/DocumentRendererShmemChild.h
src/content/canvas/public/DocumentRendererShmemParent.h
src/content/canvas/src/CustomQS_Canvas2D.h
src/content/canvas/src/CustomQS_WebGL.h
src/dbm/include/extern.h
src/dbm/include/hash.h
src/dbm/include/hsearch.h
src/dbm/include/mpool.h
src/dbm/include/ncompat.h
src/dbm/include/queue.h
src/dbm/include/search.h
src/dbm/include/winfile.h
src/dom/plugins/base/PluginPRLibrary.h
src/dom/plugins/ipc/AStream.h
src/dom/plugins/ipc/NPEventAndroid.h
src/dom/plugins/ipc/NPEventOSX.h
src/dom/plugins/ipc/NPEventWindows.h
src/dom/plugins/ipc/NPEventX11.h
src/dom/plugins/ipc/PluginLibrary.h
src/dom/plugins/ipc/PluginProcessParent.h
src/dom/plugins/ipc/PluginSurfaceParent.h
src/dom/src/geolocation/nsGeoPositionIPCSerialiser.h
src/dom/system/cocoa/nsDeviceMotionSystem.h
src/editor/libeditor/base/nsIEditorSupport.h
src/editor/txtsvc/public/nsITextService.h
src/embedding/components/printingui/src/mac/nsPrintingPromptService.h
src/embedding/components/windowwatcher/public/nsPromptUtils.h
src/gfx/angle/include/GLSLANG/ResourceLimits.h
src/gfx/angle/samples/gles2_book/Common/esUtil.h
src/gfx/angle/samples/gles2_book/Common/esUtil_win.h
src/gfx/angle/src/compiler/MMap.h
src/gfx/angle/src/libEGL/resource.h
src/gfx/angle/src/libGLESv2/resource.h
src/gfx/cairo/cairo/src/cairo-arc-private.h
src/gfx/cairo/cairo/src/cairo-boxes-private.h
src/gfx/cairo/cairo/src/cairo-combsort-private.h
src/gfx/cairo/cairo/src/cairo-composite-rectangles-private.h
src/gfx/cairo/cairo/src/cairo-drm.h
src/gfx/cairo/cairo/src/cairo-features-win32.h
src/gfx/cairo/cairo/src/cairo-fontconfig-private.h
src/gfx/cairo/cairo/src/cairo-freed-pool-private.h
src/gfx/cairo/cairo/src/cairo-ft-private.h
src/gfx/cairo/cairo/src/cairo-gl-private.h
src/gfx/cairo/cairo/src/cairo-glitz-private.h
src/gfx/cairo/cairo/src/cairo-image-info-private.h
src/gfx/cairo/cairo/src/cairo-meta-surface-private.h
src/gfx/cairo/cairo/src/cairo-no-features.h
src/gfx/cairo/cairo/src/cairo-os2-private.h
src/gfx/cairo/cairo/src/cairo-output-stream-private.h
src/gfx/cairo/cairo/src/cairo-paginated-private.h
src/gfx/cairo/cairo/src/cairo-paginated-surface-private.h
src/gfx/cairo/cairo/src/cairo-path-private.h
src/gfx/cairo/cairo/src/cairo-pdf-surface-private.h
src/gfx/cairo/cairo/src/cairo-private.h
src/gfx/cairo/cairo/src/cairo-ps-surface-private.h
src/gfx/cairo/cairo/src/cairo-quartz-private.h
src/gfx/cairo/cairo/src/cairo-recording-surface-private.h
src/gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h
src/gfx/cairo/cairo/src/cairo-script.h
src/gfx/cairo/cairo/src/cairo-skia.h
src/gfx/cairo/cairo/src/cairo-slope-private.h
src/gfx/cairo/cairo/src/cairo-supported-features.h
src/gfx/cairo/cairo/src/cairo-surface-fallback-private.h
src/gfx/cairo/cairo/src/cairo-surface-offset-private.h
src/gfx/cairo/cairo/src/cairo-surface-snapshot-private.h
src/gfx/cairo/cairo/src/cairo-surface-subsurface-private.h
src/gfx/cairo/cairo/src/cairo-surface-wrapper-private.h
src/gfx/cairo/cairo/src/cairo-svg-surface-private.h
src/gfx/cairo/cairo/src/cairo-tee-surface-private.h
src/gfx/cairo/cairo/src/cairo-truetype-subset-private.h
src/gfx/cairo/cairo/src/cairo-type1-private.h
src/gfx/cairo/cairo/src/cairo-type3-glyph-surface-private.h
src/gfx/cairo/cairo/src/cairo-user-font-private.h
src/gfx/cairo/cairo/src/cairo-vg.h
src/gfx/cairo/cairo/src/cairo-xcb-xrender.h
src/gfx/cairo/cairo/src/cairo-xcb.h
src/gfx/cairo/cairo/src/cairo-xlib-surface-private.h
src/gfx/cairo/cairo/src/cairo-xml.h
src/gfx/cairo/cairo/src/test-fallback-surface.h
src/gfx/cairo/cairo/src/test-meta-surface.h
src/gfx/cairo/cairo/src/test-paginated-surface.h
src/gfx/cairo/cairo/test/buffer_diff.h
src/gfx/cairo/cairo/test/cairo_test.h
src/gfx/cairo/cairo/test/read_png.h
src/gfx/cairo/cairo/test/write_png.h
src/gfx/cairo/cairo/test/xmalloc.h
src/gfx/cairo/libpixman/src/pixman-accessor.h
src/gfx/cairo/libpixman/src/pixman-arm-common.h
src/gfx/cairo/libpixman/src/pixman-arm-neon-asm.h
src/gfx/cairo/libpixman/src/pixman-combine32.h
src/gfx/cairo/libpixman/src/pixman-combine64.h
src/gfx/cairo/libpixman/src/pixman-edge-imp.h
src/gfx/cairo/libpixman/src/pixman-x64-mmx-emulation.h
src/gfx/harfbuzz/src/hb-blob-private.h
src/gfx/harfbuzz/src/hb-font-private.h
src/gfx/harfbuzz/src/hb-ft.h
src/gfx/harfbuzz/src/hb-glib.h
src/gfx/harfbuzz/src/hb-graphite.h
src/gfx/harfbuzz/src/hb-icu.h
src/gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.h
src/gfx/harfbuzz/src/hb-ot.h
src/gfx/harfbuzz/src/hb-unicode-private.h
src/gfx/layers/ipc/ShadowLayerUtils.h
src/gfx/layers/ipc/ShadowLayerUtilsX11.h
src/gfx/ots/src/cff_type2_charstring.h
src/gfx/ots/src/cmap.h
src/gfx/ots/src/cvt.h
src/gfx/ots/src/fpgm.h
src/gfx/ots/src/gasp.h
src/gfx/ots/src/gdef.h
src/gfx/ots/src/glyf.h
src/gfx/ots/src/gpos.h
src/gfx/ots/src/gsub.h
src/gfx/ots/src/hdmx.h
src/gfx/ots/src/head.h
src/gfx/ots/src/hhea.h
src/gfx/ots/src/hmtx.h
src/gfx/ots/src/kern.h
src/gfx/ots/src/layout.h
src/gfx/ots/src/loca.h
src/gfx/ots/src/ltsh.h
src/gfx/ots/src/maxp.h
src/gfx/ots/src/name.h
src/gfx/ots/src/post.h
src/gfx/ots/src/prep.h
src/gfx/ots/src/vdmx.h
src/gfx/ots/src/vhea.h
src/gfx/ots/src/vmtx.h
src/gfx/ots/src/vorg.h
src/gfx/qcms/qcmsint.h
src/gfx/src/BaseMargin.h
src/gfx/src/BasePoint.h
src/gfx/src/BaseRect.h
src/gfx/src/BaseSize.h
src/gfx/thebes/cairo-xlib-utils.h
src/gfx/thebes/gfxGlitzSurface.h
src/gfx/thebes/woff-private.h
src/intl/hyphenation/src/hnjalloc.h
src/intl/lwbrk/src/nsLWIMP.h
src/intl/uconv/ucvko/jamoclusters.h
src/intl/unicharutil/public/nsIUGenDetailCategory.h
src/intl/unicharutil/src/ucdata.h
src/ipc/chromium/base/file_version_info_linux.h
src/ipc/chromium/src/base/atomic_sequence_num.h
src/ipc/chromium/src/base/base_drag_source.h
src/ipc/chromium/src/base/base_drop_target.h
src/ipc/chromium/src/base/chrome_application_mac.h
src/ipc/chromium/src/base/clipboard_util.h
src/ipc/chromium/src/base/cpu.h
src/ipc/chromium/src/base/crypto/cssm_init.h
src/ipc/chromium/src/base/crypto/signature_verifier.h
src/ipc/chromium/src/base/data_pack.h
src/ipc/chromium/src/base/directory_watcher.h
src/ipc/chromium/src/base/eintr_wrapper.h
src/ipc/chromium/src/base/event_recorder.h
src/ipc/chromium/src/base/field_trial.h
src/ipc/chromium/src/base/file_util.h
src/ipc/chromium/src/base/file_version_info.h
src/ipc/chromium/src/base/float_util.h
src/ipc/chromium/src/base/foundation_utils_mac.h
src/ipc/chromium/src/base/gfx/gdi_util.h
src/ipc/chromium/src/base/gfx/gtk_native_view_id_manager.h
src/ipc/chromium/src/base/gfx/gtk_util.h
src/ipc/chromium/src/base/gfx/jpeg_codec.h
src/ipc/chromium/src/base/gfx/native_theme.h
src/ipc/chromium/src/base/gfx/platform_canvas.h
src/ipc/chromium/src/base/gfx/platform_canvas_linux.h
src/ipc/chromium/src/base/gfx/platform_canvas_mac.h
src/ipc/chromium/src/base/gfx/platform_device_linux.h
src/ipc/chromium/src/base/gfx/platform_device_mac.h
src/ipc/chromium/src/base/gfx/png_decoder.h
src/ipc/chromium/src/base/gfx/png_encoder.h
src/ipc/chromium/src/base/hmac.h
src/ipc/chromium/src/base/iat_patch.h
src/ipc/chromium/src/base/idle_timer.h
src/ipc/chromium/src/base/image_util.h
src/ipc/chromium/src/base/json_reader.h
src/ipc/chromium/src/base/json_writer.h
src/ipc/chromium/src/base/keyboard_codes.h
src/ipc/chromium/src/base/lazy_instance.h
src/ipc/chromium/src/base/linux_util.h
src/ipc/chromium/src/base/mac_util.h
src/ipc/chromium/src/base/md5.h
src/ipc/chromium/src/base/memory_debug.h
src/ipc/chromium/src/base/message_pump_android.h
src/ipc/chromium/src/base/message_pump_glib.h
src/ipc/chromium/src/base/message_pump_mac.h
src/ipc/chromium/src/base/message_pump_qt.h
src/ipc/chromium/src/base/native_library.h
src/ipc/chromium/src/base/no_windows2000_unittest.h
src/ipc/chromium/src/base/nss_init.h
src/ipc/chromium/src/base/perf_test_suite.h
src/ipc/chromium/src/base/platform_file.h
src/ipc/chromium/src/base/profiler.h
src/ipc/chromium/src/base/registry.h
src/ipc/chromium/src/base/resource_util.h
src/ipc/chromium/src/base/scoped_bstr_win.h
src/ipc/chromium/src/base/scoped_clipboard_writer.h
src/ipc/chromium/src/base/scoped_comptr_win.h
src/ipc/chromium/src/base/scoped_temp_dir.h
src/ipc/chromium/src/base/scoped_variant_win.h
src/ipc/chromium/src/base/scoped_vector.h
src/ipc/chromium/src/base/sha2.h
src/ipc/chromium/src/base/simple_thread.h
src/ipc/chromium/src/base/singleton_objc.h
src/ipc/chromium/src/base/spin_wait.h
src/ipc/chromium/src/base/stack_container.h
src/ipc/chromium/src/base/stats_counters.h
src/ipc/chromium/src/base/string_escape.h
src/ipc/chromium/src/base/string_tokenizer.h
src/ipc/chromium/src/base/sys_info.h
src/ipc/chromium/src/base/system_monitor.h
src/ipc/chromium/src/base/test_file_util.h
src/ipc/chromium/src/base/third_party/nss/sha256.h
src/ipc/chromium/src/base/third_party/purify/pure.h
src/ipc/chromium/src/base/thread_local.h
src/ipc/chromium/src/base/time_format.h
src/ipc/chromium/src/base/trace_event.h
src/ipc/chromium/src/base/tracked_objects.h
src/ipc/chromium/src/base/version.h
src/ipc/chromium/src/base/watchdog.h
src/ipc/chromium/src/base/windows_message_list.h
src/ipc/chromium/src/base/wmi_util.h
src/ipc/chromium/src/base/word_iterator.h
src/ipc/chromium/src/base/worker_pool.h
src/ipc/chromium/src/base/worker_pool_linux.h
src/ipc/chromium/src/chrome/common/accessibility_types.h
src/ipc/chromium/src/chrome/common/app_cache/app_cache_context_impl.h
src/ipc/chromium/src/chrome/common/app_cache/app_cache_dispatcher.h
src/ipc/chromium/src/chrome/common/app_cache/app_cache_dispatcher_host.h
src/ipc/chromium/src/chrome/common/bindings_policy.h
src/ipc/chromium/src/chrome/common/chrome_constants.h
src/ipc/chromium/src/chrome/common/chrome_counters.h
src/ipc/chromium/src/chrome/common/chrome_paths.h
src/ipc/chromium/src/chrome/common/chrome_paths_internal.h
src/ipc/chromium/src/chrome/common/chrome_plugin_lib.h
src/ipc/chromium/src/chrome/common/classfactory.h
src/ipc/chromium/src/chrome/common/debug_flags.h
src/ipc/chromium/src/chrome/common/devtools_messages.h
src/ipc/chromium/src/chrome/common/env_vars.h
src/ipc/chromium/src/chrome/common/extensions/user_script.h
src/ipc/chromium/src/chrome/common/gears_api.h
src/ipc/chromium/src/chrome/common/gfx/color_utils.h
src/ipc/chromium/src/chrome/common/gfx/emf.h
src/ipc/chromium/src/chrome/common/gfx/text_elider.h
src/ipc/chromium/src/chrome/common/gfx/utils.h
src/ipc/chromium/src/chrome/common/gtk_util.h
src/ipc/chromium/src/chrome/common/ipc_channel_posix.h
src/ipc/chromium/src/chrome/common/ipc_channel_win.h
src/ipc/chromium/src/chrome/common/ipc_logging.h
src/ipc/chromium/src/chrome/common/ipc_maybe.h
src/ipc/chromium/src/chrome/common/ipc_test_sink.h
src/ipc/chromium/src/chrome/common/ipc_tests.h
src/ipc/chromium/src/chrome/common/json_value_serializer.h
src/ipc/chromium/src/chrome/common/jstemplate_builder.h
src/ipc/chromium/src/chrome/common/libxml_utils.h
src/ipc/chromium/src/chrome/common/mach_message_source_mac.h
src/ipc/chromium/src/chrome/common/main_function_params.h
src/ipc/chromium/src/chrome/common/mru_cache.h
src/ipc/chromium/src/chrome/common/native_web_keyboard_event.h
src/ipc/chromium/src/chrome/common/navigation_types.h
src/ipc/chromium/src/chrome/common/net/cookie_monster_sqlite.h
src/ipc/chromium/src/chrome/common/net/dns.h
src/ipc/chromium/src/chrome/common/net/url_request_intercept_job.h
src/ipc/chromium/src/chrome/common/notification_registrar.h
src/ipc/chromium/src/chrome/common/owned_widget_gtk.h
src/ipc/chromium/src/chrome/common/page_action.h
src/ipc/chromium/src/chrome/common/page_zoom.h
src/ipc/chromium/src/chrome/common/platform_util.h
src/ipc/chromium/src/chrome/common/plugin_messages.h
src/ipc/chromium/src/chrome/common/pref_member.h
src/ipc/chromium/src/chrome/common/pref_names.h
src/ipc/chromium/src/chrome/common/pref_service.h
src/ipc/chromium/src/chrome/common/property_bag.h
src/ipc/chromium/src/chrome/common/quarantine_mac.h
src/ipc/chromium/src/chrome/common/ref_counted_util.h
src/ipc/chromium/src/chrome/common/render_messages.h
src/ipc/chromium/src/chrome/common/result_codes.h
src/ipc/chromium/src/chrome/common/security_filter_peer.h
src/ipc/chromium/src/chrome/common/sqlite_compiled_statement.h
src/ipc/chromium/src/chrome/common/task_queue.h
src/ipc/chromium/src/chrome/common/temp_scaffolding_stubs.h
src/ipc/chromium/src/chrome/common/time_format.h
src/ipc/chromium/src/chrome/common/unzip.h
src/ipc/chromium/src/chrome/common/url_constants.h
src/ipc/chromium/src/chrome/common/visitedlink_common.h
src/ipc/chromium/src/chrome/common/win_safe_util.h
src/ipc/chromium/src/chrome/common/win_util.h
src/ipc/chromium/src/chrome/common/worker_messages.h
src/ipc/chromium/src/chrome/common/worker_thread_ticker.h
src/ipc/chromium/src/chrome/common/x11_util_internal.h
src/ipc/chromium/src/testing/gtest/include/gtest/gtest-spi.h
src/ipc/chromium/src/third_party/libevent/compat/sys/_time.h
src/ipc/chromium/src/third_party/libevent/evdns.h
src/ipc/chromium/src/third_party/libevent/event-internal.h
src/ipc/chromium/src/third_party/libevent/evhttp.h
src/ipc/chromium/src/third_party/libevent/evrpc-internal.h
src/ipc/chromium/src/third_party/libevent/evrpc.h
src/ipc/chromium/src/third_party/libevent/log.h
src/ipc/chromium/src/third_party/libevent/mac/config.h
src/ipc/chromium/src/third_party/libevent/strlcpy-internal.h
src/ipc/chromium/src/third_party/libevent/test/regress.gen.h
src/ipc/chromium/src/third_party/libevent/test/regress.h
src/ipc/glue/AsyncChannel.h
src/ipc/glue/BrowserProcessSubThread.h
src/ipc/glue/IOThreadChild.h
src/ipc/glue/ProcessChild.h
src/ipc/glue/SharedMemoryBasic_android.h
src/ipc/glue/SharedMemoryBasic_chromium.h
src/ipc/glue/SyncChannel.h
src/ipc/glue/Transport.h
src/ipc/glue/Transport_posix.h
src/ipc/glue/Transport_win.h
src/ipc/ipdl/test/cxx/IPDLUnitTestTypes.h
src/jpeg/cdjpeg.h
src/jpeg/jchuff.h
src/jpeg/jdct.h
src/jpeg/jdhuff.h
src/jpeg/jmemsys.h
src/jpeg/jpegcomp.h
src/jpeg/jsimd.h
src/jpeg/jsimddct.h
src/jpeg/jversion.h
src/jpeg/simd/jsimdcfg.inc.h
src/jpeg/transupp.h
src/js/ipc/CPOWTypes.h
src/js/ipc/ContextWrapperChild.h
src/js/ipc/ContextWrapperParent.h
src/js/ipc/ObjectWrapperChild.h
src/js/ipc/ObjectWrapperParent.h
src/js/jetpack/Handle.h
src/js/jetpack/JetpackActorCommon.h
src/js/jetpack/JetpackChild.h
src/js/jetpack/JetpackParent.h
src/js/jetpack/JetpackProcessChild.h
src/js/jetpack/JetpackProcessParent.h
src/js/jetpack/JetpackService.h
src/js/jsd/jsd.h
src/js/jsd/resource.h
src/js/src/config/gcc_hidden.h
src/js/src/config/mkdepend/def.h
src/js/src/config/mkdepend/ifparser.h
src/js/src/config/mkdepend/imakemdep.h
src/js/src/config/pathsub.h
src/js/src/ctypes/libffi/include/ffi_common.h
src/js/src/ctypes/libffi/src/alpha/ffitarget.h
src/js/src/ctypes/libffi/src/arm/ffitarget.h
src/js/src/ctypes/libffi/src/avr32/ffitarget.h
src/js/src/ctypes/libffi/src/cris/ffitarget.h
src/js/src/ctypes/libffi/src/frv/ffitarget.h
src/js/src/ctypes/libffi/src/ia64/ffitarget.h
src/js/src/ctypes/libffi/src/ia64/ia64_flags.h
src/js/src/ctypes/libffi/src/m32r/ffitarget.h
src/js/src/ctypes/libffi/src/m68k/ffitarget.h
src/js/src/ctypes/libffi/src/mips/ffitarget.h
src/js/src/ctypes/libffi/src/moxie/ffitarget.h
src/js/src/ctypes/libffi/src/pa/ffitarget.h
src/js/src/ctypes/libffi/src/powerpc/asm.h
src/js/src/ctypes/libffi/src/powerpc/ffitarget.h
src/js/src/ctypes/libffi/src/s390/ffitarget.h
src/js/src/ctypes/libffi/src/sh/ffitarget.h
src/js/src/ctypes/libffi/src/sh64/ffitarget.h
src/js/src/ctypes/libffi/src/sparc/ffitarget.h
src/js/src/ctypes/libffi/src/x86/ffitarget.h
src/js/src/ctypes/libffi/testsuite/libffi.call/ffitest.h
src/js/src/ctypes/libffi/testsuite/libffi.special/ffitestcxx.h
src/js/src/editline/editline.h
src/js/src/jscpucfg.h
src/js/src/methodjit/NunboxAssembler.h
src/js/src/methodjit/PunboxAssembler.h
src/js/src/resource.h
src/js/src/v8-dtoa/cached-powers.h
src/js/src/v8-dtoa/conversions.h
src/js/src/v8-dtoa/double.h
src/js/src/v8-dtoa/dtoa.h
src/js/src/v8-dtoa/fast-dtoa.h
src/js/src/v8-dtoa/v8.h
src/js/src/xpconnect/src/nsCSSPropertiesQS.h
src/js/src/xpconnect/src/nsDOMQS.h
src/js/src/xpconnect/src/qsWinUndefs.h
src/js/src/yarr/VMTags.h
src/layout/base/PaintTracker.h
src/layout/style/GroupRule.h
src/layout/style/ImportRule.h
src/layout/style/Loader.h
src/layout/style/NameSpaceRule.h
src/layout/style/Rule.h
src/media/libnestegg/include/nestegg-stdint.h
src/media/libnestegg/include/nestegg.h
src/media/libnestegg/src/align.h
src/media/libnestegg/src/halloc.h
src/media/libnestegg/src/hlist.h
src/media/libogg/include/ogg/config_types.h
src/media/libsydneyaudio/include/sydney_audio.h
src/media/libtheora/include/theora/codec.h
src/media/libtheora/include/theora/theora.h
src/media/libtheora/include/theora/theoraenc.h
src/media/libtheora/lib/apiwrapper.h
src/media/libtheora/lib/arm/armbits.h
src/media/libtheora/lib/arm/armcpu.h
src/media/libtheora/lib/arm/armint.h
src/media/libtheora/lib/bitpack.h
src/media/libtheora/lib/config.h
src/media/libtheora/lib/dct.h
src/media/libtheora/lib/decint.h
src/media/libtheora/lib/dequant.h
src/media/libtheora/lib/huffdec.h
src/media/libtheora/lib/huffman.h
src/media/libtheora/lib/mathops.h
src/media/libtheora/lib/ocintrin.h
src/media/libtheora/lib/quant.h
src/media/libtheora/lib/state.h
src/media/libtheora/lib/x86/mmxloop.h
src/media/libtheora/lib/x86/sse2trans.h
src/media/libtheora/lib/x86/x86cpu.h
src/media/libtheora/lib/x86/x86int.h
src/media/libtheora/lib/x86_vc/mmxloop.h
src/media/libtheora/lib/x86_vc/x86cpu.h
src/media/libtheora/lib/x86_vc/x86int.h
src/media/libtremor/lib/block.h
src/media/libtremor/lib/lsp_lookup.h
src/media/libtremor/lib/mdct.h
src/media/libtremor/lib/mdct_lookup.h
src/media/libtremor/lib/registry.h
src/media/libtremor/lib/window.h
src/media/libtremor/lib/window_lookup.h
src/media/libvorbis/lib/lookup.h
src/media/libvorbis/lib/lookup_data.h
src/media/libvorbis/lib/lpc.h
src/media/libvorbis/lib/lsp.h
src/media/libvorbis/lib/masking.h
src/media/libvorbis/lib/registry.h
src/media/libvorbis/lib/scales.h
src/media/libvorbis/lib/window.h
src/media/libvpx/vp8/common/alloccommon.h
src/media/libvpx/vp8/common/coefupdateprobs.h
src/media/libvpx/vp8/common/common.h
src/media/libvpx/vp8/common/defaultcoefcounts.h
src/media/libvpx/vp8/common/entropymode.h
src/media/libvpx/vp8/common/extend.h
src/media/libvpx/vp8/common/findnearmv.h
src/media/libvpx/vp8/common/g_common.h
src/media/libvpx/vp8/common/invtrans.h
src/media/libvpx/vp8/common/onyx.h
src/media/libvpx/vp8/common/pragmas.h
src/media/libvpx/vp8/common/predictdc.h
src/media/libvpx/vp8/common/preproc.h
src/media/libvpx/vp8/common/quant_common.h
src/media/libvpx/vp8/common/reconinter.h
src/media/libvpx/vp8/common/reconintra.h
src/media/libvpx/vp8/common/reconintra4x4.h
src/media/libvpx/vp8/common/setupintrarecon.h
src/media/libvpx/vp8/common/swapyv12buffer.h
src/media/libvpx/vp8/common/systemdependent.h
src/media/libvpx/vp8/common/vpxerrors.h
src/media/libvpx/vp8/decoder/decodemv.h
src/media/libvpx/vp8/decoder/decoderthreading.h
src/media/libvpx/vp8/decoder/detokenize.h
src/media/libvpx/vp8/decoder/reconintra_mt.h
src/media/libvpx/vpx/vp8e.h
src/media/libvpx/vpx_mem/include/vpx_mem_intrnl.h
src/media/libvpx/vpx_ports/arm.h
src/media/libvpx/vpx_ports/vpx_timer.h
src/media/libvpx/vpx_scale/scale_mode.h
src/media/libvpx/vpx_scale/vpxscale.h
src/media/libvpx/vpx_scale/yv12extend.h
src/media/libvpx/vpx_version.h
src/memory/jemalloc/ql.h
src/memory/jemalloc/qr.h
src/memory/jemalloc/rb.h
src/memory/mozalloc/mozalloc.h
src/memory/mozalloc/mozalloc_abort.h
src/memory/mozalloc/mozalloc_macro_wrappers.h
src/memory/mozalloc/mozalloc_oom.h
src/memory/mozalloc/mozalloc_undef_macro_wrappers.h
src/memory/mozalloc/msvc_raise_wrappers.h
src/memory/mozalloc/msvc_throw_wrapper.h
src/memory/mozalloc/throw_gcc.h
src/memory/mozalloc/throw_msvc.h
src/mfbt/RangedPtr.h
src/mfbt/RefPtr.h
src/mfbt/Types.h
src/mfbt/Util.h
src/mobile/components/build/nsBrowserComponents.h
src/modules/freetype2/builds/amiga/include/freetype/config/ftconfig.h
src/modules/freetype2/builds/amiga/include/freetype/config/ftmodule.h
src/modules/freetype2/builds/unix/ft2unix.h
src/modules/freetype2/builds/vms/ftconfig.h
src/modules/freetype2/devel/ftoption.h
src/modules/freetype2/include/freetype/config/ftconfig.h
src/modules/freetype2/include/freetype/config/ftmodule.h
src/modules/freetype2/include/freetype/config/ftoption.h
src/modules/freetype2/include/freetype/config/ftstdlib.h
src/modules/freetype2/include/freetype/freetype.h
src/modules/freetype2/include/freetype/ftadvanc.h
src/modules/freetype2/include/freetype/ftbbox.h
src/modules/freetype2/include/freetype/ftbdf.h
src/modules/freetype2/include/freetype/ftbitmap.h
src/modules/freetype2/include/freetype/ftcache.h
src/modules/freetype2/include/freetype/ftchapters.h
src/modules/freetype2/include/freetype/ftcid.h
src/modules/freetype2/include/freetype/fterrdef.h
src/modules/freetype2/include/freetype/fterrors.h
src/modules/freetype2/include/freetype/ftgasp.h
src/modules/freetype2/include/freetype/ftglyph.h
src/modules/freetype2/include/freetype/ftgxval.h
src/modules/freetype2/include/freetype/ftgzip.h
src/modules/freetype2/include/freetype/ftincrem.h
src/modules/freetype2/include/freetype/ftlcdfil.h
src/modules/freetype2/include/freetype/ftlist.h
src/modules/freetype2/include/freetype/ftlzw.h
src/modules/freetype2/include/freetype/ftmac.h
src/modules/freetype2/include/freetype/ftmm.h
src/modules/freetype2/include/freetype/ftmodapi.h
src/modules/freetype2/include/freetype/ftmoderr.h
src/modules/freetype2/include/freetype/ftotval.h
src/modules/freetype2/include/freetype/ftoutln.h
src/modules/freetype2/include/freetype/ftpfr.h
src/modules/freetype2/include/freetype/ftrender.h
src/modules/freetype2/include/freetype/ftsizes.h
src/modules/freetype2/include/freetype/ftsnames.h
src/modules/freetype2/include/freetype/ftstroke.h
src/modules/freetype2/include/freetype/ftsynth.h
src/modules/freetype2/include/freetype/ftsystem.h
src/modules/freetype2/include/freetype/fttrigon.h
src/modules/freetype2/include/freetype/fttypes.h
src/modules/freetype2/include/freetype/ftwinfnt.h
src/modules/freetype2/include/freetype/ftxf86.h
src/modules/freetype2/include/freetype/internal/autohint.h
src/modules/freetype2/include/freetype/internal/ftcalc.h
src/modules/freetype2/include/freetype/internal/ftdebug.h
src/modules/freetype2/include/freetype/internal/ftdriver.h
src/modules/freetype2/include/freetype/internal/ftgloadr.h
src/modules/freetype2/include/freetype/internal/ftmemory.h
src/modules/freetype2/include/freetype/internal/ftobjs.h
src/modules/freetype2/include/freetype/internal/ftpic.h
src/modules/freetype2/include/freetype/internal/ftrfork.h
src/modules/freetype2/include/freetype/internal/ftserv.h
src/modules/freetype2/include/freetype/internal/ftstream.h
src/modules/freetype2/include/freetype/internal/fttrace.h
src/modules/freetype2/include/freetype/internal/ftvalid.h
src/modules/freetype2/include/freetype/internal/internal.h
src/modules/freetype2/include/freetype/internal/pcftypes.h
src/modules/freetype2/include/freetype/internal/psaux.h
src/modules/freetype2/include/freetype/internal/pshints.h
src/modules/freetype2/include/freetype/internal/services/svbdf.h
src/modules/freetype2/include/freetype/internal/services/svcid.h
src/modules/freetype2/include/freetype/internal/services/svgldict.h
src/modules/freetype2/include/freetype/internal/services/svgxval.h
src/modules/freetype2/include/freetype/internal/services/svkern.h
src/modules/freetype2/include/freetype/internal/services/svmm.h
src/modules/freetype2/include/freetype/internal/services/svotval.h
src/modules/freetype2/include/freetype/internal/services/svpfr.h
src/modules/freetype2/include/freetype/internal/services/svpostnm.h
src/modules/freetype2/include/freetype/internal/services/svpscmap.h
src/modules/freetype2/include/freetype/internal/services/svpsinfo.h
src/modules/freetype2/include/freetype/internal/services/svsfnt.h
src/modules/freetype2/include/freetype/internal/services/svttcmap.h
src/modules/freetype2/include/freetype/internal/services/svtteng.h
src/modules/freetype2/include/freetype/internal/services/svttglyf.h
src/modules/freetype2/include/freetype/internal/services/svwinfnt.h
src/modules/freetype2/include/freetype/internal/services/svxf86nm.h
src/modules/freetype2/include/freetype/internal/sfnt.h
src/modules/freetype2/include/freetype/internal/t1types.h
src/modules/freetype2/include/freetype/internal/tttypes.h
src/modules/freetype2/include/freetype/t1tables.h
src/modules/freetype2/include/freetype/ttnameid.h
src/modules/freetype2/include/freetype/tttags.h
src/modules/freetype2/include/freetype/ttunpat.h
src/modules/freetype2/include/ft2build.h
src/modules/freetype2/src/autofit/afangles.h
src/modules/freetype2/src/autofit/afcjk.h
src/modules/freetype2/src/autofit/afdummy.h
src/modules/freetype2/src/autofit/aferrors.h
src/modules/freetype2/src/autofit/afindic.h
src/modules/freetype2/src/autofit/aflatin.h
src/modules/freetype2/src/autofit/aflatin2.h
src/modules/freetype2/src/autofit/afloader.h
src/modules/freetype2/src/autofit/afmodule.h
src/modules/freetype2/src/autofit/afpic.h
src/modules/freetype2/src/autofit/afwarp.h
src/modules/freetype2/src/base/basepic.h
src/modules/freetype2/src/base/ftbase.h
src/modules/freetype2/src/bdf/bdfdrivr.h
src/modules/freetype2/src/bdf/bdferror.h
src/modules/freetype2/src/cache/ftccback.h
src/modules/freetype2/src/cache/ftcerror.h
src/modules/freetype2/src/cff/cffcmap.h
src/modules/freetype2/src/cff/cffdrivr.h
src/modules/freetype2/src/cff/cfferrs.h
src/modules/freetype2/src/cff/cffgload.h
src/modules/freetype2/src/cff/cffload.h
src/modules/freetype2/src/cff/cffpic.h
src/modules/freetype2/src/cff/cfftoken.h
src/modules/freetype2/src/cid/ciderrs.h
src/modules/freetype2/src/cid/cidgload.h
src/modules/freetype2/src/cid/cidload.h
src/modules/freetype2/src/cid/cidriver.h
src/modules/freetype2/src/cid/cidtoken.h
src/modules/freetype2/src/gxvalid/gxvfeat.h
src/modules/freetype2/src/gxvalid/gxvmod.h
src/modules/freetype2/src/gxvalid/gxvmorx.h
src/modules/freetype2/src/gzip/infblock.h
src/modules/freetype2/src/gzip/infcodes.h
src/modules/freetype2/src/gzip/inffixed.h
src/modules/freetype2/src/gzip/inftrees.h
src/modules/freetype2/src/gzip/infutil.h
src/modules/freetype2/src/gzip/zutil.h
src/modules/freetype2/src/lzw/ftzopen.h
src/modules/freetype2/src/otvalid/otvcommn.h
src/modules/freetype2/src/otvalid/otvgpos.h
src/modules/freetype2/src/otvalid/otvmod.h
src/modules/freetype2/src/pcf/pcf.h
src/modules/freetype2/src/pcf/pcfdrivr.h
src/modules/freetype2/src/pcf/pcferror.h
src/modules/freetype2/src/pcf/pcfread.h
src/modules/freetype2/src/pcf/pcfutil.h
src/modules/freetype2/src/pfr/pfrcmap.h
src/modules/freetype2/src/pfr/pfrdrivr.h
src/modules/freetype2/src/pfr/pfrerror.h
src/modules/freetype2/src/pfr/pfrgload.h
src/modules/freetype2/src/pfr/pfrload.h
src/modules/freetype2/src/pfr/pfrsbit.h
src/modules/freetype2/src/psaux/afmparse.h
src/modules/freetype2/src/psaux/psauxerr.h
src/modules/freetype2/src/psaux/psauxmod.h
src/modules/freetype2/src/psaux/psconv.h
src/modules/freetype2/src/psaux/psobjs.h
src/modules/freetype2/src/psaux/t1cmap.h
src/modules/freetype2/src/psaux/t1decode.h
src/modules/freetype2/src/pshinter/pshalgo.h
src/modules/freetype2/src/pshinter/pshmod.h
src/modules/freetype2/src/pshinter/pshnterr.h
src/modules/freetype2/src/pshinter/pshpic.h
src/modules/freetype2/src/psnames/psmodule.h
src/modules/freetype2/src/psnames/psnamerr.h
src/modules/freetype2/src/psnames/pspic.h
src/modules/freetype2/src/psnames/pstables.h
src/modules/freetype2/src/raster/ftmisc.h
src/modules/freetype2/src/raster/ftraster.h
src/modules/freetype2/src/raster/ftrend1.h
src/modules/freetype2/src/raster/rasterrs.h
src/modules/freetype2/src/raster/rastpic.h
src/modules/freetype2/src/sfnt/sfdriver.h
src/modules/freetype2/src/sfnt/sferrors.h
src/modules/freetype2/src/sfnt/sfntpic.h
src/modules/freetype2/src/sfnt/sfobjs.h
src/modules/freetype2/src/sfnt/ttcmapc.h
src/modules/freetype2/src/sfnt/ttkern.h
src/modules/freetype2/src/sfnt/ttmtx.h
src/modules/freetype2/src/sfnt/ttpost.h
src/modules/freetype2/src/sfnt/ttsbit.h
src/modules/freetype2/src/smooth/ftgrays.h
src/modules/freetype2/src/smooth/ftsmerrs.h
src/modules/freetype2/src/smooth/ftsmooth.h
src/modules/freetype2/src/smooth/ftspic.h
src/modules/freetype2/src/truetype/ttdriver.h
src/modules/freetype2/src/truetype/tterrors.h
src/modules/freetype2/src/truetype/ttgload.h
src/modules/freetype2/src/truetype/ttgxvar.h
src/modules/freetype2/src/truetype/ttpic.h
src/modules/freetype2/src/truetype/ttpload.h
src/modules/freetype2/src/type1/t1afm.h
src/modules/freetype2/src/type1/t1driver.h
src/modules/freetype2/src/type1/t1errors.h
src/modules/freetype2/src/type1/t1gload.h
src/modules/freetype2/src/type1/t1load.h
src/modules/freetype2/src/type1/t1tokens.h
src/modules/freetype2/src/type42/t42drivr.h
src/modules/freetype2/src/type42/t42error.h
src/modules/freetype2/src/type42/t42parse.h
src/modules/freetype2/src/winfonts/fnterrs.h
src/modules/freetype2/src/winfonts/winfnt.h
src/modules/libbz2/src/bzlib_private.h
src/modules/libimg/png/pngpriv.h
src/modules/libmar/src/mar_private.h
src/modules/libpr0n/decoders/icon/mac/nsIconChannel.h
src/modules/libpref/public/PPrefTuple.h
src/modules/libpref/public/Preferences.h
src/modules/libreg/include/VerReg.h
src/modules/libreg/src/reg.h
src/modules/zlib/src/crc32.h
src/modules/zlib/src/deflate.h
src/modules/zlib/src/gzguts.h
src/modules/zlib/src/inffast.h
src/modules/zlib/src/inffixed.h
src/modules/zlib/src/inflate.h
src/modules/zlib/src/inftrees.h
src/modules/zlib/src/trees.h
src/netwerk/base/src/nsIOThreadPool.h
src/netwerk/cookie/CookieServiceChild.h
src/netwerk/cookie/CookieServiceParent.h
src/netwerk/ipc/ChannelEventQueue.h
src/netwerk/ipc/NeckoChild.h
src/netwerk/ipc/NeckoCommon.h
src/netwerk/ipc/NeckoMessageUtils.h
src/netwerk/ipc/NeckoParent.h
src/netwerk/protocol/ftp/FTPChannelChild.h
src/netwerk/protocol/ftp/FTPChannelParent.h
src/netwerk/protocol/http/HttpChannelChild.h
src/netwerk/protocol/http/HttpChannelParent.h
src/netwerk/protocol/wyciwyg/WyciwygChannelParent.h
src/netwerk/socket/nsSOCKS4SocketProvider.h
src/nsprpub/config/gcc_hidden.h
src/nsprpub/config/libc_r.h
src/nsprpub/config/pathsub.h
src/nsprpub/config/prdepend.h
src/nsprpub/lib/msgc/include/gcint.h
src/nsprpub/pr/include/obsolete/pralarm.h
src/nsprpub/pr/include/prcountr.h
src/nsprpub/pr/include/private/pprmwait.h
src/nsprpub/pr/include/private/primpl.h
src/nsprpub/pr/include/prolock.h
src/nsprpub/pr/include/prpdce.h
src/nsprpub/pr/include/prvrsion.h
src/nsprpub/pr/src/cplus/rcascii.h
src/nsprpub/pr/src/cplus/rcmon.h
src/nsprpub/pr/tests/prttools.h
src/nsprpub/pr/tests/ut_ttools.h
src/other-licenses/7zstub/src/7zip/Common/MSBFDecoder.h
src/other-licenses/7zstub/src/7zip/Common/MSBFEncoder.h
src/other-licenses/7zstub/src/7zip/MyVersion.h
src/other-licenses/android/ba.h
src/other-licenses/android/bionic_tls.h
src/other-licenses/android/linker.h
src/other-licenses/android/linker_debug.h
src/other-licenses/atk-1.0/atk/atk-enum-types.h
src/other-licenses/nsis/Contrib/ApplicationID/resource.h
src/other-licenses/nsis/Contrib/ExDLL/exdll.h
src/parser/expat/lib/ascii.h
src/parser/expat/lib/asciitab.h
src/parser/expat/lib/iasciitab.h
src/parser/expat/lib/internal.h
src/parser/expat/lib/latin1tab.h
src/parser/expat/lib/nametab.h
src/parser/expat/lib/utf8tab.h
src/parser/expat/lib/xmlrole.h
src/parser/expat/lib/xmltok_impl.h
src/parser/htmlparser/public/nsIHTMLFragmentContentSink.h
src/rdf/datasource/public/nsIRDFFTP.h
src/security/coreconf/mkdepend/def.h
src/security/coreconf/mkdepend/ifparser.h
src/security/coreconf/mkdepend/imakemdep.h
src/security/coreconf/nsinstall/pathsub.h
src/security/manager/android_stub.h
src/security/nss/cmd/certutil/certutil.h
src/security/nss/cmd/crlutil/crlgen.h
src/security/nss/cmd/lib/NSPRerrs.h
src/security/nss/cmd/lib/SECerrs.h
src/security/nss/cmd/lib/SSLerrs.h
src/security/nss/cmd/lib/pk11table.h
src/security/nss/cmd/libpkix/testutil/testutil.h
src/security/nss/cmd/libpkix/testutil/testutil_nss.h
src/security/nss/cmd/modutil/install-ds.h
src/security/nss/cmd/modutil/install.h
src/security/nss/cmd/modutil/installparse.h
src/security/nss/cmd/modutil/modutil.h
src/security/nss/cmd/pk12util/pk12util.h
src/security/nss/cmd/signtool/signtool.h
src/security/nss/cmd/signtool/zip.h
src/security/nss/cmd/vfyserv/vfyserv.h
src/security/nss/lib/certdb/certxutl.h
src/security/nss/lib/ckfw/builtins/builtins.h
src/security/nss/lib/ckfw/capi/ckcapi.h
src/security/nss/lib/ckfw/capi/nsscapi.h
src/security/nss/lib/ckfw/ck.h
src/security/nss/lib/ckfw/dbm/ckdbm.h
src/security/nss/lib/ckfw/nssmkey/ckmk.h
src/security/nss/lib/ckfw/nssmkey/nssmkey.h
src/security/nss/lib/crmf/cmmfi.h
src/security/nss/lib/crmf/crmffut.h
src/security/nss/lib/cryptohi/keyi.h
src/security/nss/lib/dev/ckhelper.h
src/security/nss/lib/dev/devm.h
src/security/nss/lib/freebl/blapii.h
src/security/nss/lib/freebl/camellia.h
src/security/nss/lib/freebl/des.h
src/security/nss/lib/freebl/ec.h
src/security/nss/lib/freebl/ecl/ec2.h
src/security/nss/lib/freebl/ecl/ecl-curve.h
src/security/nss/lib/freebl/ecl/ecp_fp.h
src/security/nss/lib/freebl/intel-aes.h
src/security/nss/lib/freebl/loader.h
src/security/nss/lib/freebl/mpi/logtab.h
src/security/nss/lib/freebl/mpi/montmulf.h
src/security/nss/lib/freebl/mpi/mp_gf2m-priv.h
src/security/nss/lib/freebl/mpi/mp_gf2m.h
src/security/nss/lib/freebl/mpi/mpprime.h
src/security/nss/lib/freebl/mpi/utils/bbs_rand.h
src/security/nss/lib/freebl/mpi/vis_proto.h
src/security/nss/lib/freebl/nsslowhash.h
src/security/nss/lib/freebl/rijndael.h
src/security/nss/lib/freebl/secmpi.h
src/security/nss/lib/freebl/secrng.h
src/security/nss/lib/freebl/seed.h
src/security/nss/lib/freebl/sha256.h
src/security/nss/lib/freebl/sha_fast.h
src/security/nss/lib/freebl/shsign.h
src/security/nss/lib/freebl/stubs.h
src/security/nss/lib/jar/jarint.h
src/security/nss/lib/jar/jzlib.h
src/security/nss/lib/libpkix/pkix/params/pkix_buildparams.h
src/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.h
src/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
src/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.h
src/security/nss/lib/nss/nssrenam.h
src/security/nss/lib/pk11wrap/dev3hack.h
src/security/nss/lib/pk11wrap/secmodi.h
src/security/nss/lib/pk11wrap/secmodti.h
src/security/nss/lib/pk11wrap/secpkcs5.h
src/security/nss/lib/pkcs12/p12local.h
src/security/nss/lib/pkcs7/p7local.h
src/security/nss/lib/pki/pki3hack.h
src/security/nss/lib/pki/pkim.h
src/security/nss/lib/pki/pkistore.h
src/security/nss/lib/smime/cmslocal.h
src/security/nss/lib/softoken/legacydb/keydbi.h
src/security/nss/lib/softoken/legacydb/lgdb.h
src/security/nss/lib/softoken/legacydb/lowkeyi.h
src/security/nss/lib/softoken/legacydb/pcert.h
src/security/nss/lib/softoken/lgglue.h
src/security/nss/lib/softoken/lowkeyi.h
src/security/nss/lib/softoken/lowpbe.h
src/security/nss/lib/softoken/pk11pars.h
src/security/nss/lib/softoken/pkcs11ni.h
src/security/nss/lib/softoken/sftkdb.h
src/security/nss/lib/softoken/sftkdbti.h
src/security/nss/lib/softoken/sftkpars.h
src/security/nss/lib/softoken/softkver.h
src/security/nss/lib/softoken/softoken.h
src/security/nss/lib/sqlite/sqlite3.h
src/security/nss/lib/ssl/os2_err.h
src/security/nss/lib/ssl/preenc.h
src/security/nss/lib/ssl/sslimpl.h
src/security/nss/lib/ssl/sslmutex.h
src/security/nss/lib/ssl/unix_err.h
src/security/nss/lib/ssl/win32err.h
src/security/nss/lib/util/nsslocks.h
src/security/nss/lib/util/nssutil.h
src/security/nss/lib/util/pkcs11.h
src/security/nss/lib/util/portreg.h
src/security/nss/lib/util/secplcy.h
src/security/nss/lib/zlib/crc32.h
src/security/nss/lib/zlib/deflate.h
src/security/nss/lib/zlib/inffast.h
src/security/nss/lib/zlib/inffixed.h
src/security/nss/lib/zlib/inflate.h
src/security/nss/lib/zlib/inftrees.h
src/security/nss/lib/zlib/trees.h
src/security/nss/tests/pkcs11/netscape/suites/security/pkcs11/pk11test.h
src/security/nss/tests/pkcs11/netscape/suites/security/ssl/sslc.h
src/security/nss/tests/pkcs11/netscape/trivial/acconfig.h
src/startupcache/StartupCache.h
src/storage/public/StatementCache.h
src/storage/public/storage.h
src/toolkit/components/alerts/mac/growl/CFGrowlAdditions.h
src/toolkit/components/alerts/mac/growl/CFMutableDictionaryAdditions.h
src/toolkit/components/alerts/mac/growl/CFURLAdditions.h
src/toolkit/components/alerts/mac/growl/GrowlAbstractSingletonObject.h
src/toolkit/components/alerts/mac/growl/GrowlApplicationBridge.h
src/toolkit/components/alerts/mac/growl/GrowlDefines.h
src/toolkit/components/alerts/mac/growl/GrowlDefinesInternal.h
src/toolkit/components/alerts/mac/growl/GrowlPathUtilities.h
src/toolkit/components/alerts/mac/growl/GrowlPathway.h
src/toolkit/components/alerts/mac/growl/GrowlPreferencesController.h
src/toolkit/components/alerts/mac/growl/GrowlTicketController.h
src/toolkit/components/alerts/mac/mozGrowlDelegate.h
src/toolkit/components/alerts/mac/nsAlertsImageLoadListener.h
src/toolkit/components/alerts/mac/nsNotificationsList.h
src/toolkit/components/startup/nsUserInfoMac.h
src/toolkit/crashreporter/client/crashreporter_osx.h
src/toolkit/crashreporter/google-breakpad/src/breakpad_googletest_includes.h
src/toolkit/crashreporter/google-breakpad/src/client/linux/android_link.h
src/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/directory_reader.h
src/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/line_reader.h
src/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_extension_linux.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/Inspector.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_exc_server.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/handler/breakpad_nlist_64.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/handler/minidump_generator.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/handler/protected_memory_allocator.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/DynamicImagesTests.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/breakpad_nlist_test.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/handler/testcases/dwarftests.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/sender/crash_report_sender.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/Controller.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/testapp/TestClass.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/tests/SimpleStringDictionaryTest.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/tests/auto_tempdir.h
src/toolkit/crashreporter/google-breakpad/src/client/mac/tests/testlogging.h
src/toolkit/crashreporter/google-breakpad/src/client/minidump_file_writer-inl.h
src/toolkit/crashreporter/google-breakpad/src/client/windows/common/auto_critical_section.h
src/toolkit/crashreporter/google-breakpad/src/client/windows/tests/crash_generation_app/precompile.h
src/toolkit/crashreporter/google-breakpad/src/client/windows/unittests/dump_analysis.h
src/toolkit/crashreporter/google-breakpad/src/common/convert_UTF.h
src/toolkit/crashreporter/google-breakpad/src/common/dwarf/bytereader-inl.h
src/toolkit/crashreporter/google-breakpad/src/common/dwarf/cfi_assembler.h
src/toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.h
src/toolkit/crashreporter/google-breakpad/src/common/dwarf/line_state_machine.h
src/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.h
src/toolkit/crashreporter/google-breakpad/src/common/dwarf_cu_to_module.h
src/toolkit/crashreporter/google-breakpad/src/common/dwarf_line_to_module.h
src/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.h
src/toolkit/crashreporter/google-breakpad/src/common/linux/eintr_wrapper.h
src/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.h
src/toolkit/crashreporter/google-breakpad/src/common/linux/google_crashdump_uploader.h
src/toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/GTMDefines.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/GTMGarbageCollection.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/GTMLogger.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/SimpleStringDictionary.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/byteswap.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/dump_syms.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/file_id.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/macho_id.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/scoped_task_suspend-inl.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/string_utilities.h
src/toolkit/crashreporter/google-breakpad/src/common/mac/testing/GTMSenTestCase.h
src/toolkit/crashreporter/google-breakpad/src/common/solaris/dump_symbols.h
src/toolkit/crashreporter/google-breakpad/src/common/solaris/file_id.h
src/toolkit/crashreporter/google-breakpad/src/common/solaris/guid_creator.h
src/toolkit/crashreporter/google-breakpad/src/common/solaris/message_output.h
src/toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.h
src/toolkit/crashreporter/google-breakpad/src/common/string_conversion.h
src/toolkit/crashreporter/google-breakpad/src/common/testdata/func-line-pairing.h
src/toolkit/crashreporter/google-breakpad/src/common/windows/guid_string.h
src/toolkit/crashreporter/google-breakpad/src/common/windows/http_upload.h
src/toolkit/crashreporter/google-breakpad/src/common/windows/pdb_source_line_writer.h
src/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/call_stack.h
src/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump_processor.h
src/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/network_source_line_resolver.h
src/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/process_state.h
src/toolkit/crashreporter/google-breakpad/src/processor/address_map-inl.h
src/toolkit/crashreporter/google-breakpad/src/processor/basic_code_module.h
src/toolkit/crashreporter/google-breakpad/src/processor/basic_code_modules.h
src/toolkit/crashreporter/google-breakpad/src/processor/contained_range_map-inl.h
src/toolkit/crashreporter/google-breakpad/src/processor/network_source_line_protocol.h
src/toolkit/crashreporter/google-breakpad/src/processor/network_source_line_server.h
src/toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.h
src/toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator-inl.h
src/toolkit/crashreporter/google-breakpad/src/processor/range_map-inl.h
src/toolkit/crashreporter/google-breakpad/src/processor/simple_symbol_supplier.h
src/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_amd64.h
src/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_arm.h
src/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_ppc.h
src/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_sparc.h
src/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_unittest_utils.h
src/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.h
src/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.h
src/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump_unittest_data.h
src/toolkit/crashreporter/google-breakpad/src/processor/windows_frame_info.h
src/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/gflags/gflags_completions.h
src/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/glog/logging.h
src/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/glog/raw_logging.h
src/toolkit/crashreporter/google-breakpad/src/third_party/linux/include/glog/stl_logging.h
src/toolkit/crashreporter/google-breakpad/src/tools/mac/crash_report/on_demand_symbol_supplier.h
src/toolkit/crashreporter/google-breakpad/src/tools/windows/converter/ms_symbol_server_converter.h
src/toolkit/xre/MozMeegoAppService.h
src/tools/codesighs/msmap.h
src/tools/trace-malloc/spacetrace.h
src/uriloader/exthandler/mac/nsLocalHandlerAppMac.h
src/uriloader/exthandler/mac/nsMIMEInfoMac.h
src/uriloader/exthandler/mac/nsOSHelperAppService.h
src/widget/public/WidgetTraceEvent.h
src/widget/public/nsGUIEventIPC.h
src/widget/src/cocoa/ComplexTextInputPanel.h
src/widget/src/cocoa/CustomCocoaEvents.h
src/widget/src/cocoa/GfxInfo.h
src/widget/src/cocoa/nsAppShell.h
src/widget/src/cocoa/nsBidiKeyboard.h
src/widget/src/cocoa/nsChildView.h
src/widget/src/cocoa/nsClipboard.h
src/widget/src/cocoa/nsCocoaWindow.h
src/widget/src/cocoa/nsCursorManager.h
src/widget/src/cocoa/nsDeviceContextSpecX.h
src/widget/src/cocoa/nsDragService.h
src/widget/src/cocoa/nsFilePicker.h
src/widget/src/cocoa/nsIdleServiceX.h
src/widget/src/cocoa/nsLookAndFeel.h
src/widget/src/cocoa/nsMacDockSupport.h
src/widget/src/cocoa/nsMenuItemIconX.h
src/widget/src/cocoa/nsMenuItemX.h
src/widget/src/cocoa/nsMenuUtilsX.h
src/widget/src/cocoa/nsNativeThemeCocoa.h
src/widget/src/cocoa/nsNativeThemeColors.h
src/widget/src/cocoa/nsPrintDialogX.h
src/widget/src/cocoa/nsPrintOptionsX.h
src/widget/src/cocoa/nsPrintSettingsX.h
src/widget/src/cocoa/nsScreenManagerCocoa.h
src/widget/src/cocoa/nsSound.h
src/widget/src/cocoa/nsStandaloneNativeMenu.h
src/widget/src/cocoa/nsWindowMap.h
src/widget/src/gtk2/maiRedundantObjectFactory.h
src/widget/src/gtkxtbin/xembed.h
src/widget/src/os2/nsGfxDefs.h
src/xpcom/base/FunctionTimer.h
src/xpcom/base/nsAllocator.h
src/xpcom/base/nsCom.h
src/xpcom/base/nsIID.h
src/xpcom/base/pure.h
src/xpcom/build/Services.h
src/xpcom/build/XPCOM.h
src/xpcom/components/Module.h
src/xpcom/components/ModuleLoader.h
src/xpcom/components/ModuleUtils.h
src/xpcom/ds/nsIPersistentProperties.h
src/xpcom/glue/AutoRestore.h
src/xpcom/glue/BlockingResourceBase.h
src/xpcom/glue/CondVar.h
src/xpcom/glue/FileUtils.h
src/xpcom/glue/GenericFactory.h
src/xpcom/glue/IntentionalCrash.h
src/xpcom/glue/Monitor.h
src/xpcom/glue/Mutex.h
src/xpcom/glue/ReentrantMonitor.h
src/xpcom/glue/nsThreadIDs.h
src/xpcom/glue/unused.h
src/xpcom/tests/resources.h
src/xpcom/typelib/xpidl/xpidl.h

The following cpp files are being included:
src/browser/app/nsBrowserApp.cpp includes src/toolkit/xre/nsWindowsWMain.cpp
src/gfx/angle/src/compiler/MozAngleLink.cpp includes src/gfx/angle/src/compiler/Link.cpp
src/gfx/thebes/gfxUnicodeProperties.cpp includes src/gfx/thebes/gfxUnicodePropertyData.cpp
src/ipc/app/MozillaRuntimeMain.cpp includes src/toolkit/xre/nsWindowsWMain.cpp
src/ipc/ipdl/test/cxx/app/TestIPDL.cpp includes src/toolkit/xre/nsWindowsWMain.cpp
src/js/src/jsinvoke.cpp includes src/js/src/jsinterp.cpp
src/mobile/app/nsBrowserApp.cpp includes src/toolkit/xre/nsWindowsWMain.cpp
src/toolkit/mozapps/update/updater/updater.cpp includes src/toolkit/xre/nsWindowsRestart.cpp
src/toolkit/xre/nsAppRunner.cpp includes src/toolkit/xre/nsWindowsRestart.cpp
src/toolkit/xre/nsWindowsWMain.cpp includes src/toolkit/xre/nsWindowsDllBlocklist.cpp
src/toolkit/xre/test/win/TestXREMakeCommandLineWin.cpp includes src/toolkit/xre/nsWindowsRestart.cpp
src/xpcom/string/src/nsDependentString.cpp includes src/xpcom/string/src/nsTDependentString.cpp
src/xpcom/string/src/nsDependentSubstring.cpp includes src/xpcom/string/src/nsTDependentSubstring.cpp
src/xpcom/string/src/nsPromiseFlatString.cpp includes src/xpcom/string/src/nsTPromiseFlatString.cpp
src/xpcom/string/src/nsString.cpp includes src/xpcom/string/src/nsTString.cpp
src/xpcom/string/src/nsStringComparator.cpp includes src/xpcom/string/src/nsTStringComparator.cpp
src/xpcom/string/src/nsStringObsolete.cpp includes src/xpcom/string/src/nsTStringObsolete.cpp
src/xpcom/string/src/nsSubstring.cpp includes src/xpcom/string/src/nsTSubstring.cpp
src/xpcom/string/src/nsSubstringTuple.cpp includes src/xpcom/string/src/nsTSubstringTuple.cpp
src/xpcom/tests/TestStaticAtoms.cpp includes src/xpcom/tests/MoreTestingAtoms.cpp
src/xpcom/tests/TestStaticAtoms.cpp includes src/xpcom/tests/TestingAtoms.cpp
src/xulrunner/app/nsXULRunnerApp.cpp includes src/toolkit/xre/nsWindowsWMain.cpp
src/xulrunner/stub/nsXULStub.cpp includes src/toolkit/xre/nsWindowsWMain.cpp

The following files are included more than once by the same file:
None