Theory of operation
-------------------

Uncrustify goes through several steps to reformat code.
The first step, parsing, is the most complex and important.


Step 1 - parsing
----------------
C code must be understood to some degree to be able to be properly indented.
The parsing step reads in a text buffer and breaks it into chunks and puts
those chunks in a list.

When a chunk is parsed, the original column and line are recorded.

These are the chunks that are parsed:
 - punctuators
 - numbers
 - words (keywords, variables, etc)
 - comments
 - strings
 - whitespace
 - preprocessors

In the code, chunk types are prefixed with 'CT_'.
The interesting chunk type is CT_WORD, which can be types, variables, or
keywords.

The nesting level is recorded.
Special care is taken with unbraced do/if/else/for/switch/while bodies.
Virtual braces are inserted around unbraced bodies to ensure proper indenting.

Also during this step, simple identification is done.
For example, if a CT_WORD follows CT_ENUM/CT_STRUCT/CT_UNION, then it is marked
as a CT_TYPE.
If a '*' follows CT_TYPE, then it is a CT_PTR_TYPE.
If a CT_WORD is followed by an open parenthesis, the it is a CT_FUNCTION.
Parenthesis and braces are marked where appropriate.


Step 2 - Indentification
------------------------

In the next step, more complicated identification is done.
This step does the following:
 - finds and marks casts
 - finds and marks variable definitions (for aligning)
 - finds and marks assignments that may be aligned
 - changes CT_INCDEC_AFTER to CT_INCDEC_BEFORE
 - changes CT_STAR to either CT_PTR_TYPE, CT_DEREF or CT_ARITH
 - changes CT_MINUS to either CT_NEG or CT_ARITH
 - changes CT_PLUS and CT_ADDR to CT_ARITH, if needed

The chunks must also be identified to be useful.
This is done through some simple pattern matching.

Casts
-----
Casts are detected as follows:
 - paren pair not part of if/for/etc nor part of a function
 - contains only CT_QUALIFIER, CT_TYPE, '*', and no more than one CT_WORD
 - is not followed by CT_ARITH

Tough cases:
(foo) * bar;


A chunk starts a statement if:
 - after { or }
 - after ';', but not if the paren stack top is a paren
 - after '(' that has a parent type of CT_FOR

