Слияние C Callergraphs с Doxygen или определение объединения всех вызовов - PullRequest
4 голосов
/ 26 января 2009

У меня есть коллекция устаревшего кода C, который я реорганизую, чтобы отделить вычислительный код C от GUI. Это усложняется из-за сильно рекурсивного математического основного кода, являющегося объявлениями в стиле K & R. Я уже отказался от попытки преобразовать их в объявления ANSI из-за вложенного использования параметров функции (просто не удалось получить последние 4 ошибки компилятора).

Мне нужно переместить некоторые файлы в чистую DLL и определить минимальный интерфейс для публикации, что потребует написания функций-оболочек для публикации типизированного интерфейса.

Я разметил ключевые исходные файлы с помощью разметки Doxygen @callergraph, поэтому для отдельных функций создаются информативные графики. Кроме того, я хотел бы объединить эти графики, чтобы я мог определить самую узкую границу функций, открытых внешнему миру.

Оригинальные заголовочные файлы бесполезны - они представляют все как нетипизированные функции языка Си.

Существуют сотни функций, поэтому простая проверка сгенерированных коллографов является болезненной.

Я подумываю написать какой-нибудь инструмент для слияния DOT - установка DOT_CLEANUP = NO заставляет Doxygen оставлять там промежуточные файлы DOT, а не просто сохранять сгенерированные ими файлы png.

Я не одержим этим графическим решением - я был бы весьма рад, если бы кто-то мог предложить альтернативный инструмент анализа (бесплатный или относительно дешевый) или методику, использующую вывод Doxygen XML для достижения той же цели.

Диаграмма, объединенная на уровне файлов, имеет определенную привлекательность для клиентской документации, а не для простого списка: -)

Ответы [ 3 ]

5 голосов
/ 29 августа 2009

В вашем Doxyfile установите

GENERATE_XML = YES

и тогда вы можете найти график вызовов в файлах XML. Для каждой функции, отмеченной графом вызывающего абонента, вы найдете в выводе <referencedby> элементов, которые вы можете использовать. Вот пример из одного из моих файлов C:

  <memberdef kind="function" id="spfs_8c_1a3"
             prot="public" static="yes" const="no" explicit="no"
             inline="no" virt="non-virtual">
    <type>svn_error_t *</type>
    <definition>svn_error_t * init_apr</definition>
    <argsstring>(apr_pool_t **ppool, int *argc, char const *const **argv)</argsstring>
    <name>init_apr</name>
    <!-- param and description elements clipped for brevity ... -->
    <location file="src/spfs.c" line="26" bodystart="101" bodyend="120"/>
    <referencedby refid="spfs_8c_1a13" compoundref="spfs_8c"
                  startline="45" endline="94">main</referencedby>
  </memberdef>

Таким образом, для каждой пары memberdef / referencedby у вас есть отношение вызывающего абонента, которое вы можете получить через XSLT:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="text"/>

    <xsl:template match="/">
        <xsl:apply-templates select="//memberdef[@kind eq 'function']"/>
    </xsl:template>

    <xsl:template match="memberdef">
        <xsl:variable name="function-name"
                      select="concat(definition, argsstring)"/>
        <xsl:for-each select="referencedby">
            <xsl:value-of select="concat(./text(), ' calls ', $function-name, '&#xA;')"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Что дает вам строку для каждого вызывающего абонента, как это:

main calls svn_error_t * init_apr(apr_pool_t **ppool, int *argc, char const *const **argv)

Вы захотите настроить этот XSLT, а затем разбить этот направленный граф так, чтобы он проходил через наименьшее количество ребер. Woo Hoo, NP-полная проблема! К счастью, на эту тему есть много статей, некоторые здесь: http://www.sandia.gov/~bahendr/partitioning.html

1 голос
/ 20 февраля 2013

У меня было похожее требование. Написал Perl-скрипт для объединения набора файлов точек в один файл точек.

https://github.com/bharanis/scripts/blob/master/doxygen_dot_merge.pl

объединить несколько сгенерированных doxygen файлов точек. Это полезно для создания карты вызовов для файла или группы файлов.

1) Эта команда должна выполняться вне каталога html, куда doxygen помещает все файлы html, dot и map.

2) Эта команда предполагает плоскую структуру каталогов, используемую в doxygen CREATE_SUBDIRS = NO

3) doxygen добавляет префикс исходного файла к имени файла выходной точки. Для каждой функции генерируется один файл точек

4) предоставить список сгенерированных doxygen файлов точек для объединения. например:

./doxydotmerge.pl  `ls html/ssd_*_8c*_cgraph.dot  | grep -v test | grep -v buf`
0 голосов
/ 16 августа 2009

Вы могли бы использовать Scientific Toolworks, чтобы увидеть график вызовов всей системы.

Если вы хотите автоматизировать анализ и резку, вы можете рассмотреть инструментарий реинжиниринга программного обеспечения DMS. Может рассчитывать полные графы вызовов для C (в комплекте с точечным анализом для указателей функций), и был проверено для систем с 35 миллионами строк кода. Будет создавать полные системные файлы DOT для проверки; они довольно большие, но вы можете выбрать подмножества, чтобы посмотреть. См. анализ потока и графики вызовов .

...