• Stars
    star
    181
  • Rank 212,110 (Top 5 %)
  • Language
    Python
  • License
    MIT License
  • Created about 8 years ago
  • Updated almost 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple Python script that simplifies C++ compiler errors. Useful when using heavily-templated libraries.

camomilla

license gratipay badge.python3

What is it?

camomilla is a simple Python 3 script that simplifies errors produced by C++ compilers. It is very useful while dealing with heavily-templated code (e.g. when using boost::hana or boost::fusion).

camomilla transforms the error text to make it easier to read. It supports JSON configuration files that can include each other recursively and caches the last error so that the user can quickly reprocess the original error with different transformation options.

Example errors

The table below shows the size reduction of the errors in the example_errors folder. The original error was generated from a real project, ecst, by simply mispelling a member field name in a template-heavy context.

Bytes (original) Bytes (after camomilla) Relative size change
g++ 6.1.1 38487 3680 -90.43%
clang++ 3.8.1 16856 2990 -82.26%

A size reduction often means that the error is easier to pinpoint. Using -r (--reprocess) to incrementally "add detail" to the error is then a good approach to gather more information on its cause/origin.

Here's a (partial) screenshot of the original g++ error - it couldn't fit in my terminal window.

Terminal screenshot: original error

Here's the full screenshot of the the same error, processed by camomilla.

Terminal screenshot: processed error

Solution or workaround?

camomilla is merely a workaround for the fact that compilers do not filter (either automatically or through flags) the depth of template typenames. Errors in projects making use of libraries such as boost::hana or boost::fusion therefore include a lot of "typename boilerplate" that can make the error harder to read.

Library developers are sometimes forced to make use of techniques to erase the long typenames in order to simplify the errors and decrease compilation time: boost::experimental::di is an example.

I think this is something that should be addressed directly in the compilers - I've created a feature request/bug report both in the GCC Bug Tracker and in the Clang Bug Tracker.

Transformations

camomilla performs the following text transformations:

  1. Template typename collapsing.

    Nested template typenames are collapsed to a specific user-defined depth. This is the most useful transformation executed by camomilla. Example:

    echo "metavector<metatype<metawhatever<int>>>::method()" | camomilla -d0
    # outputs
    metavector<?>::method()
    
    echo "metavector<metatype<metawhatever<int>>>::method()" | camomilla -d1
    # outputs
    metavector<metatype<?>>::method()
    
    echo "metavector<metatype<metawhatever<int>>>::method()" | camomilla -d2
    # outputs
    metavector<metatype<metawhatever<?>>>::method()
    
    echo "metavector<metatype<metawhatever<int>>>::method()" | camomilla -d3
    # outputs
    metavector<metatype<metawhatever<int>>>::method()

    This is incredibly useful when using template metaprogramming libraries, that usually internally nest a huge amount of wrappers.

  2. Namespace replacement regexes.

    A simple transformation from a long namespace symbol to a shorter (or absent) one.

    echo "std::vector<std::pair<std::int16_t, std::int32_t>>" | camomilla --depth=100
    # outputs
    vector<pair<int16_t, int32_t>>
    
    echo "boost::hana::tuple<boost::hana::tuple<boost::hana::int_c<10>, boost::hana::int_c<15>>>" | camomilla -d100
    # outputs
    bh::tuple<bh::tuple<bh::int_c<10>, bh::int_c<15>>>
  3. Generic replacement regexes.

    echo "std::forward<decltype(std::tuple<unsigned long long, std::size_t, int>)>(x)" | camomilla -d100
    # outputs
    fwd<decltype(tuple<ulong long, sz_t, int>)>(x)

Usage

Error redirection

Errors produced by compilers can be easily piped into camomilla:

# Pipe both `stdout` and `stderr` into `camomilla`
g++ ./x.cpp |& camomilla -d5

If |& is not supported by your shell or if you want to compare the original error to the processed one, using a temporary file is a good solution:

# Redirect both `stdout` and `stderr` into `error.out`
g++ ./x.cpp &> error.out

# Process the error
cat error | camomilla -d2

Reprocessing

The last processed original error is cached (unless --no-temp-cache is specified). It is possible to reuse the source of the last error to perform different transformations, ignoring stdin. This is particularly useful when playing with the --depth parameter to get the required typename information while avoiding clutter.

# Process error
g++ ./x.cpp |& camomilla -d0

# Whoops! Need more typename information.
camomilla -r -d1

# Still a little bit more...
camomilla -r -d2

Configuration

Argparse-generated help

usage: camomilla [-h] [--template-collapsing | --no-template-collapsing]
                 [--namespace-replacements | --no-namespace-replacements]
                 [--generic-replacements | --no-generic-replacements]
                 [--process-by-line | --no-process-by-line]
                 [--temp-cache | --no-temp-cache] [-r | --no-reprocess]
                 [--reprocess-prev-config | --no-reprocess-prev-config] [-d X]
                 [-c P]

optional arguments:
  -h, --help                   show this help message and exit
  --template-collapsing        | Control template collapsing
  --no-template-collapsing     '
  --namespace-replacements     | Control namespace replacements
  --no-namespace-replacements  '
  --generic-replacements       | Control generic replacements
  --no-generic-replacements    '
  --process-by-line            | Control process by line
  --no-process-by-line         '
  --temp-cache                 | Control temp cache
  --no-temp-cache              '
  -r, --reprocess              | Control reprocess previous source
  --no-reprocess               '
  --reprocess-prev-config      | Control reprocess with previous configuration
  --no-reprocess-prev-config   '
  -d X, --depth X              Template collapsing depth
  -c P, --config P             Configuration file path(s)

Basic command-line options

Enable/disable transformations

Error text transformations can be turned on and off individually by using the following flags. All transformations are on by default.

# Template typename collapsing (default: ON)
--template-collapsing
--no-template-collapsing

# Namespace replacement regexes (default: ON)
--namespace-replacements
--no-namespace-replacements

# Generic replacement regexes (default: ON)
--generic-replacements
--no-generic-replacements

Enable/disable temporary cache

camomilla stores the last processed original error (and last used configuration) in your OS-dependant temp folder. This option can be controlled with:

# Temporary "last error cache" (default: ON)
--temp-cache
--no-temp-cache

Reprocessing

If an error has been cached, camomilla can be invoked with reprocessing options to read directly from the cache (ignoring standard input):

# Reprocess cached error (default: OFF)
-r
--reprocess
--no-reprocess

# Reprocess with cached configuration (default: ON)
--reprocess-prev-config
--no-reprocess-prev-config

Template typename collapsing options

The depth of the template typename collapsing transformation can be specified with the -d (or --depth) flag.

# Collapse all templates with depth `>= 5`
camomilla -d5

# Collapse all templates with depth `>= 100`
camomilla --depth=100

Process by line

By default, camomilla processes the error line by line. This behavior can be disabled (in order to process the error all at once) with the --no-process-by-line flag.

Configuration files

Configurations files are JSON documents that allow users to define their namespace replacement regexes and generic replacement regexes. They also allow users to override command-line arguments (or set unspecified options). Configuration files can refer to each other recursively.

Using configuration files

Any number of configuration file paths can be passed to camomilla through the -c (or --config) flag. Configuration files are read sequentially (the order matters for option overriding).

# Executes `camomilla` reading `conf0.json`
camomilla -c"conf0.json"

# Executes `camomilla` reading `conf0.json` first, then `conf1.json`
camomilla -c"conf0.json" -c"conf1.json"

Here's a more complex example:

# Executes `camomilla` with:
# * Template typename collapsing depth: 4
# * Namespace replacement regexes: off
# * Reading the `~/camomilla_configs/test.json` file
camomilla -d4 --no-namespace-replacements -c"~/camomilla_configs/test.json"

# `test.json` may:
# * Override the specified depth
# * Override the specified `--no-namespace-replacements` option
# * Set unspecified options (e.g. `--no-generic-replacements`)

Writing configuration files

Configuration files are written in JSON. Here's an example file with complete syntax:

{
    // Set/override options
    "enableTemplateCollapsing": false,
    "enableNamespaceReplacements": false,
    "enableTuplePairReplacements": false,
    "enableGenericReplacements": false,
    "templateCollapsingDepth": 10,

    // Add namespace replacements
    "namespaceReplacements": [
        "std": "",
        "boost::hana": "bh",
        "boost::fusion": "bf",
        "boost::spirit": "bs",
    ],

    // Add generic replacements
    "genericReplacements" : [
        "tuple": "tpl",
        "forward": "fwd"
    ],

    // Include other config files
    "configPaths": [
        "~/camomilla_configs/boost_spirit.json",
        "~/camomilla_configs/limit_template_depth.json"
    ]
}

Multiple configuration files

When multiple configuration files are passed as command-line arguments, or if any configuration file "includes" another file, the behavior is as follows:

  • Options, such as enableTemplateCollapsing or templateCollapsingDepth, are overridden or set.

    • Previously set options will be potentially overwritten by the next configuration file(s).
  • Namespace replacements and generic replacements will be accumulated or overridden.

    • If a configuration file has a replacement with the same key as a previous one, its value will be overridden.

    • If a configuration file defines a replacement that wasn't previously seen, it will be added without replacing any existing replacement.

More Repositories

1

SSVOpenHexagon

C++20 FOSS clone of "Super Hexagon". Depends on SSVStart, SSVEntitySystem, SSVLuaWrapper, SSVMenuSystem, JSONcpp, SFML2.0. Features JSON/LUA customizable game files, a soundtrack by BOSSFIGHT, pseudo-3D effects.
C
609
star
2

ecst

[WIP] Experimental C++14 multithreaded compile-time entity-component-system library.
C++
460
star
3

Tutorials

Repository for my YouTube tutorials + code snippets
C++
228
star
4

quakevr

Quake VR mod supporting room-scale movement, hand interactions, and melee attacks.
C++
186
star
5

scelta

(experimental) Syntactic sugar for variant and optional types.
C++
149
star
6

cppcon2015

Repository for the slides and the code of my CppCon 2015 talks.
C++
94
star
7

cppcon2014

Repository for the slides and the code of my "Quick game development with C++11/C++14" CppCon 2014 talk.
C++
88
star
8

SSVUtils

[HEADER-ONLY] C++14 multi-purpose utility library that only depends on the STL.
C++
61
star
9

vr-game-checklist

Checklist for Virtual Reality game developers.
54
star
10

vittorioromeo.info

Latest iteration of my static webpage/blog generator
Assembly
51
star
11

cppnow2016

Repository for my C++Now 2016 sessions.
Assembly
41
star
12

bcs_thesis

My bachelor's thesis on the Entity-Component-System pattern and ECST
TeX
37
star
13

vrm_core

Lightweight C++14 utility library. (Modernized, stripped and cleaned-up version of SSVUtils.)
C++
33
star
14

SSVSCollision

[HEADER-ONLY] C++14 AABB simple collision detection/response framework for games. Depends on SSVStart, SFML2.0. It has nice performance. Features interchangeable spatial partitioning and resolution systems, a way to prevent the "crack problem", easy to use C++11 lambda callbacks for collision events. It's not perfect, but it should work very well for any simple 2D game.
C++
30
star
15

orizzonte

WIP
Assembly
26
star
16

unosolo

Work-in-progress Rust application that converts C++ header-only libraries to single self-contained headers.
Rust
26
star
17

SSVBloodshed

C++14 arcade game, spiritual successor to "Operation Carnage"
C++
22
star
18

SSVEntitySystem

[HEADER-ONLY] C++14 simple entity/component system for realtime games. Simplicity of use is preferred over a real "entity-component-system" hierarchy. Components update and draw themselves (users create their own components and override the virtual methods). Fast, easy to use and to expand. Should be fine for any simple game.
C++
20
star
19

meetingcpp2016

Repository for my Meeting C++ 2016 sessions.
Assembly
18
star
20

vscode-expand-selection-to-scope

Extension that introduces a command to incrementally expand the selection to the nearest outer scope.
TypeScript
18
star
21

DelversChoice

Game originally created for GGJ2015...
C++
15
star
22

SSVStart

[HEADER-ONLY] C++14 SFML2.0 application/game development framework. Features asset loading, windows, cameras, file system, logging, vector calculations, and many other game-dev oriented features.
C++
15
star
23

vrm_pp

Small C++ preprocessor library
C++
13
star
24

Experiments

Experimental/work-in-progress code
Assembly
11
star
25

oreilly

Material and work for O'Reilly courses and publications
C++
11
star
26

presentations

Repository containing all my presentations/tutorials/talks.
10
star
27

cpponsea2019

Repository for my "C++ On Sea 2019" talks.
10
star
28

meetingcpp2015

My Meeting C++ lightning talks: "Meaningful Casts" and "Static If".
C++
10
star
29

git-ws

C++14 command line utility (git plugin) to work with multiple git repositories at once
C++
9
star
30

accu2018

Repository for my ACCU 2018 presentations.
9
star
31

cppcon2021

Repository for my CppCon 2021 talks.
8
star
32

VeeGen

(ABANDONED) 2D terrain/dungeon generation library for games
C#
8
star
33

DiscountCpp

[HEADER-ONLY] C++11 wrapper for the markdown library "Discount"
C++
8
star
34

majsdown

WIP
C++
7
star
35

cppnow2015

Repository for my C++Now 2015 Lightning Talk: "for_each_arg explained and expanded"
C++
7
star
36

Specimen

(ABANDONED) An example game using SFMLStart, VeeEntitySystem2012, VeeCollision and VeeShadow
C#
6
star
37

cppcon2019

Repository for my CppCon 2019 talks.
6
star
38

cppnow2019

Repository for my C++ Now 2019 talks.
5
star
39

sokoban-rs-cpp

C++
5
star
40

cppnow2017

Repository for my C++Now 2017 talks.
5
star
41

cpplondon

Repository for my C++ London Meetup talks.
Shell
5
star
42

SSVLuaWrapper

[HEADER-ONLY] A C++11 LUA wrapper written by Tomaka17. The original project is discontinued. I created a repository with the original code, remove the non-C++11 parts and formatted it. I take no credit. This is a good project and I believe it should be maintained (and expanded) by someone experienced with C++ and LUA.
C++
5
star
43

NetLayer

[C++14] (University project) (WIP) - Modern C++ library that allows users to quickly create efficient callback-based network applications, binding packets to functions at compile-time and abstracting away the underlying communication protocol.
C++
5
star
44

accu2017

Repository for my ACCU 2017 presentations.
5
star
45

AutoSyncGen

Networking project for UNIME
TeX
4
star
46

cppnow2018

Repository for my C++Now 2018 talks.
4
star
47

accu2021

Repository for my ACCU 2021 talks.
4
star
48

SFMLStart

(ABANDONED) A high-level library for SFML.NET developers
C#
4
star
49

VeeEntitySystem2012

(ABANDONED) A component-based entity system for real-time games
C#
4
star
50

VeeBulletHell

(ABANDONED) A Touhou clone I made a while ago - buggy and deprecated
C#
4
star
51

vrm_cmake

Shared CMake aliases, macros and functions (WIP)
CMake
4
star
52

latexpp

C++14 simple LaTeX preprocessor intended for personal use.
C++
4
star
53

meetingcpp2017

4
star
54

SSVMenuSystem

[HEADER-ONLY] C++14 lambda-based library for quick creation of menus. Supports multiple nested menus (categories). Supports Single/Toggle/Slider menu item types. Useful in game development or console applications-
C++
4
star
55

cppcon2016

Repository for my `cppcon2016` talk: "Implementing static control flow in C++14"
Assembly
4
star
56

db2

Experimental NoSQL projects for UNIME.
Python
3
star
57

ggj2016

WIP
C++
3
star
58

TestGenericShooter

(ABANDONED) A top-down shooting game resembling Operation Carnage
C#
3
star
59

corecpp2022

Repository for my Core C++ 2022 talks.
C++
3
star
60

ndctechtown2020

Material for my NDC TechTown 2020 workshop
C++
3
star
61

accu2019

Repository for my ACCU 2019 talks.
2
star
62

veeForum

WIP
TeX
2
star
63

cppnow2021

Repository for my C++Now 2021 talks.
2
star
64

SSVNewRogue

(EXPERIMENTAL, WIP)
C++
2
star
65

DRODRoguelike

(ABANDONED) My first completed game: a roguelike inspired by DROD
C#
2
star
66

VeeTileEngine2012

(ABANDONED) Component-based entity system for tile-based games
C#
2
star
67

SSVCrateBox

(ABANDONED) C++11 test game. Depends on SSVStart, SSVEntitySystem, SSVSCollision, SFML2.0. It is mainly used to try new features I implement in the mentioned libraries. The code is quite clean - it's a great example if you want to start using my libraries.
C++
2
star
68

GGJ2015

GlobalGameJam2015
C++
1
star
69

itcpp2015

C++
1
star
70

VeeTresette

(ABANDONED) An old Tresette game
C#
1
star
71

WEBVittorioRomeo2

New version of my website (vittorioromeo.info)
HTML
1
star
72

VeeCollision

(ABANDONED) Simple AABB collision detection and resolution library
C#
1
star
73

SSVAutoUpdater

C++14 simple utility/library to automatically update files from a server
CMake
1
star
74

SSVJsonCpp

[DEPRECATED] Now included in SSVUtilsJson - [HEADER-ONLY] Cleaned up fork of JsonCpp 0.6.0-rc2.
C++
1
star
75

UNIME

University-related projects
PHP
1
star
76

dotfiles

(OUTDATED) My config dotfiles
CSS
1
star
77

test_linuxday

1
star
78

SSVGenetic

[SCHOOL THESIS PROJECT] Genetic algorithm ant simulation
C++
1
star
79

AllocSim

Repository for my OS course project (UNIME 2015)
Python
1
star
80

SSVOpenHexagonServer

(ABANDONED)
C++
1
star
81

TestUDPChat

C++
1
star
82

cpprussia2019

Repository for my C++ Russia 2019 talks.
1
star
83

WEBVittorioRomeo

(ABANDONED) My personal website, written in C++ with CTemplate and JSONCpp
JavaScript
1
star
84

LD27

Ludum Dare #27 Entry (Theme: 10 seconds)
C++
1
star
85

TimeDRODPOF

(ABANDONED) A clone of the puzzle game DROD, featuring a component-based tile-based entity system, level editing, JPS and breadth-first fast pathfinding
C#
1
star
86

SSVRPGSystem

(EXPERIMENTAL, WIP) Simple lambda-base C++11 RPG status/inventory/... system
C++
1
star
87

accu2022

Repository for my ACCU 2022 presentations.
1
star
88

VeeTileEngineOLD

(ABANDONED) An old and deprecated tile-based game engine
C#
1
star
89

VeeShadow

(ABANDONED) AABB 2d shadow-casting library that can be adapted for field-of-view detection
C#
1
star
90

cppcon2022

Repository for my CppCon 2022 talks.
1
star
91

SSVUtilsJson

[DEPRECATED] [HEADER-ONLY] C++14 utility library that depends on SSVUtils. Includes a fork of JsonCpp.
C++
1
star
92

UNIME_numerical_calculus

Numerical calculus projects/exercises for UNIME
C++
1
star
93

SSVPiet

[SCHOOL THESIS PROJECT] Random Piet-inspired artwork generator
C++
1
star
94

VeeSharpTemplate

(ABANDONED) A C#-scripting-based C# code generator (template system)
C#
1
star
95

linuxDay2014

Presentation for the Linux Day 2014 event in Messina
1
star
96

linuxDay2013

My talk for "Linux Day 2013 - Messina - Istituto Jaci": "Sviluppo di videogiochi in Linux"
C++
1
star
97

VRDevUtils

(ABANDONED) Bash scripts and other files that may be useful when developing/building
Shell
1
star