Чего вы пытаетесь достичь этим? Исходя из описания задачи, возможно, существует гораздо более простой способ решения проблемы. Если вы уверены, что это лучший способ выполнить вашу задачу, читайте дальше.
Для этого вам потребуется реализовать какой-то элементарный синтаксический анализатор языка Си. Поскольку вы обрабатываете текст, я бы порекомендовал использовать язык сценариев, такой как perl, python или ruby, чтобы изменить ваш текст, вместо того, чтобы писать программу на C для этого.
Ваш синтаксический анализатор будет проходить по файлу по одной строке за раз, и для каждой строки он будет определять, нужно ли ему вставлять ваш макрос. Парсер должен будет отслеживать множество вещей. Во-первых, он должен отслеживать, находится ли он внутри комментария или нет. Когда вы встречаете последовательность /*
, установите флаг «в комментарии» и снимите его, когда в следующий раз встретите последовательность */
. Каждый раз, когда этот флаг установлен, вы не добавите вызов макроса. Кроме того, вам нужно будет отслеживать, находитесь ли вы внутри функции. Предполагая, что ваш код довольно прост и понятен, у вас может быть «счетчик скобок», который начинается с нуля, увеличивается при каждом обнаружении {
и уменьшается при каждом обнаружении }
. Если ваш счетчик скобок равен нулю, то вы не находитесь внутри функции и не должны добавлять вызов макроса. Вы также захотите добавить специальный код для обнаружения и игнорирования фигурных скобок, которые являются частью определения структуры, инициализатора массива и т. Д. Обратите внимание, что простой подсчет фигурных скобок не будет работать, если ваш код выполняет более сложные вещи, такие как:
void some_function (int arg) {
#ifdef CHECK_LIMIT_ONLY
if (arg == 0) {
#else
if (arg < 10) {
#endif
// some code here
...
}
}
Хотя вы можете утверждать, что фрагмент - это просто случай плохо написанного кода, это всего лишь пример типа проблемы, с которой вы можете столкнуться. Если в вашем коде есть что-то, что нарушает простой подсчет фигурных скобок, то эта проблема стала значительно сложнее. Один из способов определить, будет ли ваш код нарушать подсчет фигурных скобок, - это если вы достигнете конца файла с ненулевым счетчиком фигурных скобок или если в любой момент времени счетная скобка станет отрицательной.
Как только вы можете определить, когда вы находитесь в функции, а не в комментарии, вам нужно определить, нужен ли строке после нее макрос. Вы можете начать с нескольких простых правил, протестировать скрипт и посмотреть, есть ли пропущенные случаи. Для начала, любая строка, заканчивающаяся точкой с запятой, является концом оператора, и вы захотите вставить макрос после него. Аналогично подсчету скобок, когда вы находитесь внутри функции, вам нужно посчитать скобки, чтобы вы могли определить, находитесь ли вы внутри вызова функции, условного цикла или другого составного оператора. Если вы находитесь внутри одного из них, вы не добавите макрос. Другое местоположение кода для отслеживания - это начальная и конечная строки блока { ... }
. Если строка заканчивается на {
или }
, вы добавите макрос после нее.
Для такой сложной задачи, как эта, вам определенно захочется что-то написать, попробовать на сравнительно простом куске кода и посмотреть, что получится неправильно. Внесите коррективы, чтобы покрыть случаи, которые вы пропустили в первый раз, и повторите тестирование. Когда он сможет правильно проанализировать простой код, дайте ему что-нибудь более сложное и посмотрите, насколько хорошо он работает.
'' Обновление: '' Чтобы устранить озабоченность, выраженную некоторыми людьми относительно дополнительной задержки добавления команд печати, помните, что вам не нужно печатать временную метку при каждом вызове макроса. Вместо этого вызовите макрос, возьмите метку времени и вставьте ее в список. Как только ваша программа будет готова, выведите все временные метки из списка. Таким образом, вы сохраняете всю задержку, связанную с печатью, до окончания теста.