Первое. Нужен сильно упрощённый синтаксический анализ, который делит код на директивы препроцессора, лексемы, операторы и комментарии, понимающий вложенность операторных скобок.
Второе. Все эти лексемы выкидываем в выходной поток, добавляя незначащие символы по всоему усмотрению.
Третье. Комментарии тоже придётся переформатировать, и с этим отдельный геморрой.
Для Си — там есть ещё #define. Идеал — развернуть каждый #define, добавив спецсимволы «тут начало #define», «тут конец #define», форматнуть код, передвинуть левый спецсимвол как можно правее по незначащим символам (а правый — как можно левее), а потом опустить всё между спецсимволами, оставив только #define в том виде, как он был.