Mesclando C Callergraphs com Doxygen ou determinar união de todas as chamadas
-
20-08-2019 - |
Pergunta
Eu tenho uma coleção de código legado C que estou refatoração para dividir o código computacional C do GUI. Isso é complicado pelo código do núcleo matemático fortemente recursiva sendo declarações de estilo K & R. Eu já abandonou uma tentativa de convertê-los às declarações ANSI devido ao uso aninhado de parâmetros da função (apenas não poderia obter esses últimos 4 erros do compilador para ir).
Eu preciso mover alguns arquivos em um DLL pura e determinar a interface mínima de tornar público, o que vai exigir invólucro funções escrevendo para publicar uma interface digitada.
Eu tenho marcado os arquivos de origem chave com o Doxygen @callergraph marcação para gráficos informativos são gerados para funções individuais. O que eu gostaria de fazer além do que é amalgamar estes gráficos para que eu possa determinar o limite mais estreito de funções expostas para o mundo exterior.
Os arquivos de cabeçalho originais são inúteis - eles expõem tudo como funções C sem tipo
.Existem centenas de funções tão simples inspeção das callergraphs gerados é doloroso.
Estou pensando em escrever algum tipo de ferramenta de mesclagem DOT -. Configuração DOT_CLEANUP = NO faz Doxygen deixar o DOT intermediário arquivos lá em vez de apenas reter os arquivos PNG eles gerados
Eu não estou obcecado por esta ser uma solução gráfica -. Eu ficaria muito feliz se alguém poderia sugerir uma ferramenta alternativa análise (livre ou relativamente barato) ou técnica usando a saída XML do Doxygen para alcançar o mesmo objetivo
A callergraph amalgamado no nível de arquivo tem um certo apelo para documentação do cliente, em vez de uma lista simples: -)
Solução
Em seu Doxyfile, set
GENERATE_XML = YES
e então você pode encontrar o seu gráfico de chamadas nos arquivos XML. Para cada função marcada com o callergraph, você vai encontrar elementos <referencedby>
na saída que você pode usar. Aqui está um exemplo de um dos meus arquivos 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>
Assim, para cada par memberdef / referencedby, você tem um relacionamento chamador-callee, que você pode pegar via 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, '
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
que lhe dá uma linha por chamador-callee assim:
main calls svn_error_t * init_apr(apr_pool_t **ppool, int *argc, char const *const **argv)
Você vai querer ajustar que XSLT e então particionar o grafo direcionado da maneira que atravessa as bordas menor número. Woo hoo, um problema NP-completo! Felizmente, existem muitos artigos sobre o assunto, alguns aqui: http: // www. sandia.gov/~bahendr/partitioning.html
Outras dicas
Eu tinha uma exigência semelhante. Escreveu um script perl para juntar um conjunto de arquivos de pontos em um único arquivo de ponto.
https://github.com/bharanis/scripts/blob/master/ doxygen_dot_merge.pl
mesclar vários doxygen gerado dot arquivos. Isso é útil para gerar um mapa de chamada para um arquivo ou um monte de arquivos.
1) Este comando está a ser executado a partir de fora do diretório html onde coloca doxygen todo o html, dot e mapear arquivos.
2) Este comando assume estrutura de diretório plana usado em doxygen CREATE_SUBDIRS = NO
3) doxygen prefixos o nome do arquivo de origem para o nome dos arquivos de ponto de saída. Um arquivo de ponto é gerado por função
4) fornecer a lista de doxygen gerado arquivos ponto a ser incorporada. por exemplo:
./doxydotmerge.pl `ls html/ssd_*_8c*_cgraph.dot | grep -v test | grep -v buf`
Você pode usar Toolworks científicos para ver o seu gráfico de chamadas de todo o sistema.
Se você deseja automatizar a análise e o corte, você pode considerar o DMS Software Reengineering Toolkit. Pode calcular gráficos de chamadas completas para C (Completo com pontos-de análise para ponteiros de função), e tem sido comprovada para sistemas de 35 milhões de linhas de código. Será produzir completa do sistema DOT arquivos para inspecionar; eles são muito grande, mas você pode escolher subconjuntos para olhar. Consulte análise de fluxo e call gráficos .