🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)
🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)

🔧 Programmierung 🕛 kürzlich 16 Min Lesezeit
0

include-tidy: A Tool to Enforce Include-What-You-Use

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




Introduction



Unlike .






include-what-you-use



Having found include-what-you-use (iwyu), I tried it out. It sort-of worked, but gave incorrect suggestions. For example, when using getopt_long via , standard headers are defined, then any header included by one of the standard headers should automatically be considered an implementation detail and the standard headers should automatically proxy for those other headers.



Aside from that, I found iwyu less than ideal in a few other ways:




  • Some configuration is done via the aforementioned mapping files while other configuration is done via special IWYU comments in source code.


  • Iwyu has been around since 2011. As of this writing in 2026, that’s 15 years (!) and it’s still only at version 0.26. While it is under active development, it’s apparently progressing very slowly.


  • Looking at its , it’s probably going to be a while since those get fixed.


  • Part of the slowness might be due to iwyu using the (Tidy). I optimistically (naively?) thought “How hard can it be?” While the core functionality wasn’t hard (I implemented it in a couple of weeks), it’s invariably the corner cases, the last 10%, that takes 90% of the time. Even so, I’ve gotten Tidy to 1.0 in approximately two months.



    While it’s non-trivial to write a full C parser since C is (still) a relatively small language, it’ tractable for one person; but it’s simply too much work to write a full C++ parser. Instead of using the unstable Clang C++ API, I used the stable (because I’m too cheap to pay for , and wait for answers (if any).



    My use of AI does not mean include-tidy was written by AI, certainly not copied verbatim (I don’t like its coding style); but the AI certainly pointed me in the right direction.






    Configuration



    Unlike iwyu, I wanted Tidy to be fully configurable via files. The choices these days are , . IMHO, the least bad of these is TOML. Given that choice, the next task was to be able to parse TOML files.



    I looked for a TOML library with a C API and found , but it wasn’t obvious which one was better. I also didn’t like the idea of having another dependency in addition to Libclang. So I decided to implement my own TOML libary. I optimistically (naively?) thought “How hard can it be?” (Sound familiar?)



    Actually, compared to implementing Tidy, implementing a TOML library was much easier. Part of that was due to me not having to implement a full TOML parser because Tidy simply doesn’t need things like dates, times, floating-point numbers, arrays of or inline tables, multi-line strings, or Unicode.



    Tidy also implement configuration file “layering.” There can be a default, system-wide configuration file in /etc/xdg/include-tidy/config.toml (Tidy implements the as described and its output can be parsed looking for the #include <...> search starts here: and End of search list. These directories can then be added as arguments to -isystem command-line options.






    More Command-Line Parsing



    To complicate matters, the command-line arguments have to be pre-scanned to look for:




    • The last argument to get its filename extension to know what language, and thus which include directories, we need.


    • An -x option that specifies the language overriding the filename extension.


    • A --clang or -C option to allow the user to override the path to clang.




    All this before ever calling getopt_long().






    Sample include-tidy.toml Configuration File



    Not surprisingly, I now . Here’s include-tidy’s configuration file:




    CODE
    [config.h]
    ignore-as-argument = true

    [pjl_config.h]
    first = true
    keep = true
    proxy = [
    "attribute.h",
    "config.h",
    ]






    The config.h file is auto-generated by (hence the keep = true), and is a proxy for the other two, i.e., if pjl_config.h is included, then it’s as if attribute.h and config.h were included also.






    Data Structures



    The main data structure is one for an included file:




    CODE
    enum tidy_sort_rank {
    TIDY_SORT_FIRST = -2, // The very first `#include`.
    TIDY_SORT_ASSOCIATED = -1, // After first, but before default.
    TIDY_SORT_DEFAULT = 0 // Default sort rank.
    };

    typedef struct tidy_include tidy_include;
    typedef enum tidy_sort_rank tidy_sort_rank;

    struct tidy_include {
    CXFile file; // File included.
    CXFileUniqueID file_id; // Unique file ID.
    char const *abs_path; // Absolute path.
    char const *rel_path; // Relative path.
    tidy_include *includer; // Include including this.
    tidy_include *proxy; // Proxy include, if any.
    unsigned depth; // Include depth.
    array_t lines; // Line(s) included from.
    tidy_sort_rank sort_rank; // Sorting rank.
    bool elide; // Elide if necessary?
    bool keep; // Keep if unnecessary?
    bool is_local; // Local include file?
    bool is_needed; // Include needed?
    bool is_proxy_explicit; // Was proxy explicit?
    rb_tree_t symbol_set; // Symbols referenced.
    };

    rb_tree_t tidy_include_set;






    where:




    • Anything with a CX prefix is from Libclang. CXFile is just an opaque handle to a file; CXFileUniqueID is an ID Libclang uses for unique file identification. I use it as the key for tidy_include_set (that uses ).


    • lines is an array of line numbers that the file was included from. If the length > 1, it means the file was erroneously included more than once and Tidy reports this.


    • Normally when printing all include files (when requested), Tidy follows proper (AST) of the project):




      CODE
      // c_type.h
      struct c_type {
      // ...
      };

      // types.h
      typedef struct c_type c_type_t;

      // c_ast.h
      struct c_ast {
      c_type_t type;
      // ...
      };

      // dump.h
      void c_type_dump( c_type_t const *type, FILE *fout );






      Suppose we’re tidying c_ast.h. Which header(s) does it need to include? Clearly, it needs types.h because it declares the typedef for c_type_t. But c_type.h is also needed because the complete type for the c_type_tstruct c_type — is needed for the member declaration.



      In contrast, now suppose we’re tidying dump.h. Which header(s) does it need to include? Only types.h because c_type_t is used only as part of a pointer declaration and C allows incomplete types to be used just fine in such cases. (C++ is the same, but also allows incomplete types for add a whole other dimension of complication. Consider the declaration:




      CODE
      // util.h
      #define POINTER_CAST(T,EXPR) ((T)(uintptr_t)(EXPR))






      Because the macro references uintptr_t, util.h should include stdint.h so the user of the macro can treat it like a black box.



      In Libclang, macro definitions don’t form part of the AST. Instead, when a definition is encountered, you have to get all the tokens comprising it and iterate over them. But first you have to parse function-like macros’ parameters, create a set of them, and exclude them from the tokens while iterating. You also have to exclude __VA_ARGS__ and __VA_OPT__.






      The Preprocessor’s ## Operator



      Another limitation of Libclang is that symbols formed via the preprocessor’s ## (paste) operator aren’t “seen” by Libclang. Consequently, if such a symbol is declared in a header is referenced and no other symbols from that header are referenced, Tidy won't think the header is necessary. For example:




      CODE
      #include <readline/readline.h>

      #define RL_PROMPT_IGNORE(SBUF, WHEN) \
      strbuf_putc( (SBUF), RL_PROMPT_ ## WHEN ## _IGNORE )

      void prompt_create( strbuf_t *sbuf ) {
      RL_PROMPT_IGNORE( sbuf, START );
      // ...






      The expansion of RL_PROMPT_IGNORE will create RL_PROMPT_START_IGNORE that’s declared in readline.h. If no other symbols from it are referenced, Tidy will incorrectly think the header is unnecessary.



      As an alternative to not using ## here, you can add dummy code seen only by Tidy (and Libclang):




      CODE
      #ifdef __include_tidy__
      void explicitly_reference_symbols() {
      (void)RL_PROMPT_START_IGNORE;
      }
      #endif






      That is, Tidy implicitly defines __include_tidy__ when tidying. By explicitly referencing such a symbol directly via dummy code, Libclang will ”see” it and Tidy will correctly think the header is necessary. Because such code is never compiled, the code can be anything (but it still has to be legal and should not generate warnings).






      Conclusion



      Tidy was an interesting (and sometimes frustrating) project to work on. I’m sure there are still bugs, likely more-so with C++ code since most of my testing was with C code.

      Vollständiger Original-Bericht
      Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
      ↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Hackers Just Poisoned the Rust Supply Chain | Threat Wire
1 Quelle
Hackers Found a Way Into Humanoid Robots | Threat Wire
1 Quelle
Bits und so #1021 (Passwort für Laufwerk)
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten include-tidy: A Tool to Enforce Include-What-You-Use

Thematisch verwandte Begriffe: includetidy, Tool, Enforce, IncludeWhatYouUse · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...