Что касается проблемы извлечения, я думаю, я бы как-то пометил функции, которые я хочу экспортировать, а затем извлек бы это в процессе сборки.
Вы могли бы использовать «семантический макрос» в стиле gettext (то есть макрос, который ничего не делает, кроме предоставления семантической информации внешним инструментам):
#define TEST_CASE(f) f
T TEST_CASE(f)(D x, ...)
{
/* ... */
}
Затем вы можете легко извлечь это, используя sed или awk, или что угодно, и составить список в правильном формате на основе этого. Вот некоторый простой код в awk, так как это то, что я знаю лучше всего, но вы можете использовать что-то еще:
match($0, /TEST_CASE\([a-zA-Z_][a-zA-Z_0-9]*\)/) {
name = substr($0, RSTART, RLENGTH)
sub(/^TEST_CASE\(/, "", name)
sub(/\)$/, "", name)
funcs[name]
}
END {
for (f in funcs)
printf "func_type %s;\n", f
print "funcRecord funcTable[] = {"
for (f in funcs)
printf "\t{ .p_func = %s, .funcName = \"%s\" },\n", f, f
print "};"
}
Если вы собираетесь отсортировать имена (полезно для bsearch () - ing), я бы порекомендовал использовать три фильтра: фильтр извлечения (здесь уместен sed-liner), sort (1), затем Фильтр генерации (я бы использовал здесь awk). Однако вам придется сгенерировать верхний / нижний колонтитул отдельно и сделать два прохода или сохранить результат извлечения во временном файле, чтобы сгенерировать как внешние объявления, так и записи массива.
Я не думаю, что это хорошая идея - пытаться извлечь функции с помощью данного прототипа, например, пустота (пустота). Лучше использовать typedef (func_type в моем примере) и явный семантический макрос, IMHO, он более устойчив (к изменениям, а также к различным стилям кодирования, например, помещая возвращаемый тип в строку отдельно против not).
Все, что осталось сделать, - это добавить этот этап генерации в ваш make-файл, как в ответе dmckee (хотя, я думаю, вы на самом деле захотите поместить весь этот сгенерированный код в .c, а не .h). Для полноты вот моя версия:
TEST_SRCS= test1.c test2.c test3.c
test_funcs.c: ${TEST_SRCS}
echo '#include "test.h"' >$@
awk -f extract_test_funcs.awk ${TEST_SRCS} >>$@