A Doxygen comment in a .c or .h file (a block opening with slash-star-star
or slash-star-bang, a run of /// or //! lines) names code with `@ref name`
or `\ref name` (family doxygen_ref) and with the names an `@see`, `\see`,
`@sa` or `\sa` paragraph lists that have the shape of a symbol (`name`,
`name()`, `::name`, `Type::member`; family see). Code blocks, fences, code
spans, quoted labels and the word after \c, \p, \a, \b, \e, \em hold none; a
URL is the core's href family. A .h is parsed as C++, which does not change
the rule; other C++ and Objective-C files are not part of the leg.
C keeps no node for a function prototype, so the docs of a header's API
were never stored anywhere. The doc-link driver gets an optional loose_docs
hook, called after the definitions and the file's own doc: the C leg reads
every Doxygen block outside function bodies that no definition took, and
its references belong to the file (the File node is the source).
The scope ("c1") lists the definitions with nodes (function, variable,
type, enum constant, field, object-like and function-like macro) with their
qualified names, their linkage (static, or a type, constant or macro of a
.c file, is the file's own) and the parent of a constant or field, and the
pages, groups, anchors and sections the file's docs define.
doc_links_c.c resolves a name as Doxygen does, without imports:
- a page, group, anchor or section name is no code entity (graph_gap) and
never binds a symbol of the same name;
- then the documented file's own definitions (static ones too), its fields,
then what every file sees (external linkage, a header's types, constants
and macros); a static definition of another file is not visible;
- candidates count by qualified name (a prototype and its definition, #if
variants: one node); with `()` written a function or function-like macro
wins, then a definition wins over a macro;
- `Type::member`: a field of the struct or union Type, or a constant of the
enum Type;
- one candidate binds, several are ambiguous; a word of an @see paragraph
that names nothing and is a plain lowercase word is prose (Doxygen prints
it as text): no row; test code binds only from test code.
There is no scope_delta hook yet: a declaration or linkage change is a full
run.
The families are held (ships=false) until their held-out audit passes; the
suite ships them through the test seam.
Proof (ship build, Apple M5 Pro / 48 GB, base 7a321cac):
- xxhash (redis 4f20cb489344, a clean copy), the field test's 174 audited
links, 110 of which had hit a rename macro before C1: every harvested one
now names the right entity (169 edges, 2 self-mentions: XXH_NAMESPACE's
own doc); the other 3 are @copydoc, which this leg does not harvest.
- redis: doxygen_ref 74 edges (179 mentions), see 25 (30); rows: graph_gap
50, missing 6, ambiguous 3, unparseable 1. The prose rule took the 75
rows of words like "for" and "details" out.
- pico-sdk 079c6f39: doxygen_ref 488 (730), see 199 (219); rows: graph_gap
142 (groups and pages), missing 94, ambiguous 68 (one type per chip,
rp2040 and rp2350), test_only_target 28 (assembly functions with only a
C test version), unparseable 5.
- libusb abba63ed: doxygen_ref 256 (284), see 39 (44); rows: graph_gap 62,
missing 18, unparseable 2, ambiguous 2. 46 of the edges are
Type::member references.
- libevent d82464a2: see 176 (230); rows: missing 9.
- a random sample of 24 edges (8 per corpus, pico-sdk, libusb, libevent)
read against their source lines: all correct, among them a header
prototype's doc linking to the definition in the .c file.
Finding outside the leg: libevent's event_assign has no node (its return
type and name are split by an #if block), so its references are missing.
Tests (doc_mentions_c): tokens with their lines and the file-level source
of a prototype's doc; C++ files out, headers in; the scope blob; every
resolution rule; incremental equals full (a doc edit and a body edit repair
one file, a definition made static is a full run); 60 modules give the same
edges and rows with one worker and several. Each rule red with it reverted.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>