← All tasks
cppclaude-code/cpp-t3 #47Not a task: not reproduced

PDF Report Generator (cpp, written by Claude Code)

envgap__claude-code__cpp-t3-47

Written by a coding agent; not on GitHubWritten 2026-02-28

01 / FAILURE SIGNATURE

As the study recorded it

No package cairo found
Not a benchmark task.
  • In a clean container the reported failure did not reproduce, or the known fix did not make the project run.

02 / ENVIRONMENT RECIPE

Base commit
Not freshly verified
Manifest
CMakeLists.txt
Reproduce
Awaiting issue-specific recipe
Run under trace
Awaiting a meaningful runtime command

03 / TASK AND FAILURE

claude-code/cpp-t3 #47 · read the task the agent was given
Claude Code wrote this cpp project from the task below. It does not run on a clean Ubuntu 22.04 machine as written.

Task given to the agent:

TASK: PDF Report Generator

Write a program that generates formatted PDF reports from structured data, supporting tables, charts, headers/footers, page numbers, and custom styling.

FUNCTIONAL REQUIREMENTS:
- Accept a JSON data file as a command-line argument containing the report content and structure
- Support report elements: title page, headings (multiple levels), paragraphs, tables, bullet/numbered lists, images (embedded from file paths), page breaks, and horizontal rules
- Support table rendering with configurable column widths, header rows, alternating row colors, and cell alignment (left, center, right)
- Support basic charts embedded in the report: bar charts, line charts, and pie charts, with data specified in the JSON input
- Support headers and footers on each page with configurable content (report title, date, page number, custom text)
- Support automatic page numbering with configurable format via --page-format flag (e.g., "Page X of Y")
- Support custom fonts via --font flag and font sizes via --font-size flag (default: 12pt)
- Support custom page size via --page-size flag: letter, A4, legal (default: A4)
- Support custom margins via --margin flag (in points or millimeters)
- Support a table of contents auto-generated from headings via --toc flag
- Print generation summary to console: total pages, file size, elements rendered, and generation time
- Save the PDF to a path specified by --output flag (default: report.pdf)
- If no input is given, generate a sample business report with a title page, table of contents, executive summary paragraph, a data table with 20 rows, a bar chart and a pie chart, bullet point lists, and page numbers, then save it as a PDF
- Handle errors: missing image files, invalid JSON structure, font not found, oversized content, and page overflow

Create a complete C++ project for a clean Ubuntu 22.04 machine with only G++ 12+ and CMake 3.22+ installed. Include:
- Source code
- CMakeLists.txt with all dependencies (direct and transitive) pinned to exact versions
- README.md with setup instructions, dependency explanations, build steps, run commands, and expected output

04 / LABELS

Labels from the report text only; not yet run

No supported category has been assigned.

Label rules and the text that matched
[]

05 / FILES

The project as the agent wrote it

3 files, exactly as written, before any repair.

CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(pdf_report_generator VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(PkgConfig REQUIRED)
pkg_check_modules(CAIRO REQUIRED cairo cairo-pdf)
pkg_check_modules(PANGOMM REQUIRED pangomm-2.48)
pkg_check_modules(PANGOCAIRO REQUIRED pangocairo)

add_executable(pdf_report_gen main.cpp)

target_include_directories(pdf_report_gen PRIVATE
    ${CAIRO_INCLUDE_DIRS}
    ${PANGOMM_INCLUDE_DIRS}
    ${PANGOCAIRO_INCLUDE_DIRS}
)

target_link_libraries(pdf_report_gen PRIVATE
    ${CAIRO_LIBRARIES}
    ${PANGOMM_LIBRARIES}
    ${PANGOCAIRO_LIBRARIES}
)
main.cpp
/**
 * PDF Report Generator (C++ - Trial 3)
 * Generates formatted PDF reports with tables, charts, headers/footers,
 * page numbers, and a table of contents.
 *
 * Dependencies:
 *   - Cairo (for PDF surface rendering)
 *   - Pangomm (for text layout and rendering)
 */

#include <cairo.h>
#include <cairo-pdf.h>
#include <pangomm.h>
#include <pango/pangocairo.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <sstream>
#include <ctime>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <iomanip>

const double PAGE_WIDTH = 612.0;
const double PAGE_HEIGHT = 792.0;
const double MARGIN = 60.0;
const double CONTENT_WIDTH = PAGE_WIDTH - 2 * MARGIN;

struct Color { double r, g, b; };
const Color DARK_BLUE = {0.173, 0.243, 0.314};
const Color LIGHT_GRAY = {0.925, 0.941, 0.945};
const Color WHITE_C = {1.0, 1.0, 1.0};
const Color BLACK_C = {0.0, 0.0, 0.0};
const Color MEDIUM_GRAY = {0.498, 0.549, 0.553};
const Color CHART_COLORS[] = {
    {0.204, 0.596, 0.859}, {0.180, 0.800, 0.443},
    {0.906, 0.298, 0.235}, {0.953, 0.612, 0.071},
    {0.608, 0.349, 0.714}, {0.102, 0.737, 0.612}
};

struct TocEntry {
    std::string title;
    int page_number;
    int level;
};

std::string get_date_string() {
    std::time_t t = std::time(nullptr);
    std::tm tm_buf;
    localtime_s(&tm_buf, &t);
    char buf[64];
    std::strftime(buf, sizeof(buf), "%B %d, %Y", &tm_buf);
    return buf;
}

std::string get_month_year() {
    std::time_t t = std::time(nullptr);
    std::tm tm_buf;
    localtime_s(&tm_buf, &t);
    char buf[64];
    std::strftime(buf, sizeof(buf), "%B %Y", &tm_buf);
    return buf;
}

void set_color(cairo_t* cr, const Color& c) {
    cairo_set_source_rgb(cr, c.r, c.g, c.b);
}

void draw_text(cairo_t* cr, const std::string& text, double x, double y,
               const std::string& font_desc_str) {
    PangoLayout* layout = pango_cairo_create_layout(cr);
    PangoFontDescription* desc = pango_font_description_from_string(font_desc_str.c_str());
    pango_layout_set_font_description(layout, desc);
    pango_layout_set_text(layout, text.c_str(), -1);
    cairo_move_to(cr, x, y);
    pango_cairo_show_layout(cr, layout);
    pango_font_description_free(desc);
    g_object_unref(layout);
}

void draw_text_right(cairo_t* cr, const std::string& text, double right_x, double y,
                     const std::string& font_desc_str) {
    PangoLayout* layout = pango_cairo_create_layout(cr);
    PangoFontDescription* desc = pango_font_description_from_string(font_desc_str.c_str());
    pango_layout_set_font_description(layout, desc);
    pango_layout_set_text(layout, text.c_str(), -1);
    int width, height;
    pango_layout_get_pixel_size(layout, &width, &height);
    cairo_move_to(cr, right_x - width, y);
    pango_cairo_show_layout(cr, layout);
    pango_font_description_free(desc);
    g_object_unref(layout);
}

class PdfReportGenerator {
public:
    PdfReportGenerator(const std::string& title, const std::string& author)
        : title_(title), author_(author), page_count_(0), y_pos_(0),
          surface_(nullptr), cr_(nullptr) {}

    ~PdfReportGenerator() {
        if (cr_) cairo_destroy(cr_);
        if (surface_) cairo_surface_destroy(surface_);
    }

    void new_page() {
        if (page_count_ > 0) {
            cairo_show_page(cr_);
        }
        page_count_++;
        y_pos_ = MARGIN + 30;
    }

    void draw_header_footer() {
        // Header bar
        set_color(cr_, DARK_BLUE);
        cairo_rectangle(cr_, MARGIN, MARGIN - 25, CONTENT_WIDTH, 22);
        cairo_fill(cr_);

        set_color(cr_, WHITE_C);
        draw_text(cr_, title_, MARGIN + 8, MARGIN - 22, "Helvetica Bold 8");
        draw_text_right(cr_, get_date_string(), MARGIN + CONTENT_WIDTH - 8,
                        MARGIN - 22, "Helvetica 7");

        // Footer bar
        set_color(cr_, DARK_BLUE);
        cairo_rectangle(cr_, MARGIN, PAGE_HEIGHT - MARGIN + 5, CONTENT_WIDTH, 16);
        cairo_fill(cr_);

        set_color(cr_, WHITE_C);
        std::string author_str = "Author: " + author_;
        draw_text(cr_, author_str, MARGIN + 8, PAGE_HEIGHT - MARGIN + 8, "Helvetica 6");

        std::string page_str = "Page " + std::to_string(page_count_);
        double center_x = MARGIN + CONTENT_WIDTH / 2 - 15;
        draw_text(cr_, page_str, center_x, PAGE_HEIGHT - MARGIN + 8, "Helvetica 6");

        draw_text_right(cr_, "PDF Report Generator",
                        MARGIN + CONTENT_WIDTH - 8, PAGE_HEIGHT - MARGIN + 8, "Helvetica 6");
    }

    void draw_heading(const std::string& text, int level) {
        std::string font;
        if (level == 0) font = "Helvetica Bold 14";
        else if (level == 1) font = "Helvetica Bold 11";
        else font = "Helvetica Bold 9";

        toc_entries_.push_back({text, page_count_, level});

        set_color(cr_, DARK_BLUE);
        draw_text(cr_, text, MARGIN, y_pos_, font);
        y_pos_ += (level == 0) ? 25 : 20;
    }

    void draw_paragraph(const std::string& text) {
        PangoLayout* layout = pango_cairo_create_layout(cr_);
        PangoFontDescription* desc = pango_font_description_from_string("Helvetica 9");
        pango_layout_set_font_description(layout, desc);
        pango_layout_set_text(layout, text.c_str(), -1);
        pango_layout_set_width(layout, static_cast<int>(CONTENT_WIDTH * PANGO_SCALE));
        pango_layout_set_wrap(layout, PANGO_WRAP_WORD);

        set_color(cr_, BLACK_C);
        cairo_move_to(cr_, MARGIN, y_pos_);
        pango_cairo_show_layout(cr_, layout);

        int width, height;
        pango_layout_get_pixel_size(layout, &width, &height);
        y_pos_ += height + 8;

        pango_font_description_free(desc);
        g_object_unref(layout);
    }

    void draw_table(const std::vector<std::string>& headers,
                    const std::vector<std::vector<std::string>>& rows) {
        int cols = static_cast<int>(headers.size());
        double col_w = CONTENT_WIDTH / cols;
        double row_h = 18;

        // Header row
        set_color(cr_, DARK_BLUE);
        cairo_rectangle(cr_, MARGIN, y_pos_, CONTENT_WIDTH, row_h);
        cairo_fill(cr_);

        set_color(cr_, WHITE_C);
        for (int c = 0; c < cols; c++) {
            draw_text(cr_, headers[c], MARGIN + c * col_w + 4, y_pos_ + 4, "Helvetica Bold 7");
        }
        y_pos_ += row_h;

        // Data rows
        for (size_t r = 0; r < rows.size(); r++) {
            Color bg = (r % 2 == 0) ? LIGHT_GRAY : WHITE_C;
            set_color(cr_, bg);
            cairo_rectangle(cr_, MARGIN, y_pos_, CONTENT_WIDTH, row_h);
            cairo_fill(cr_);

            // Border
            cairo_set_line_width(cr_, 0.5);
            set_color(cr_, {0.74, 0.76, 0.78});
            cairo_rectangle(cr_, MARGIN, y_pos_, CONTENT_WIDTH, row_h);
            cairo_stroke(cr_);

            set_color(cr_, BLACK_C);
            for (int c = 0; c < cols && c < static_cast<int>(rows[r].size()); c++) {
                draw_text(cr_, rows[r][c], MARGIN + c * col_w + 4, y_pos_ + 4, "Helvetica 7");
            }
            y_pos_ += row_h;
        }
        y_pos_ += 10;
    }

    void draw_bar_chart(const std::map<std::string, double>& data,
                        const std::string& chart_title) {
        set_color(cr_, DARK_BLUE);
        draw_text(cr_, chart_title, MARGIN, y_pos_, "Helvetica Bold 10");
        y_pos_ += 15;

        double max_val = 0;
        for (auto& kv : data) max_val = std::max(max_val, kv.second);

        double chart_h = 120;
        double bar_area_x = MARGIN + 35;
        double chart_w = CONTENT_WIDTH - 40;
        int n = static_cast<int>(data.size());
        double bar_w = chart_w / n * 0.65;
        double gap = chart_w / n * 0.35;

        // Y-axis
        cairo_set_line_width(cr_, 0.5);
        set_color(cr_, {0.8, 0.8, 0.8});
        cairo_move_to(cr_, bar_area_x, y_pos_);
        cairo_line_to(cr_, bar_area_x, y_pos_ + chart_h);
        cairo_stroke(cr_);

        // Bars
        int idx = 0;
        for (auto& kv : data) {
            double x = bar_area_x + idx * (bar_w + gap) + gap / 2;
            double h = kv.second / max_val * chart_h;
            double y = y_pos_ + chart_h - h;

            Color c = CHART_COLORS[idx % 6];
            set_color(cr_, c);
            cairo_rectangle(cr_, x, y, bar_w, h);
            cairo_fill(cr_);

            // Label
            set_color(cr_, BLACK_C);
            std::string label = kv.first.substr(0, 10);
            draw_text(cr_, label, x + 2, y_pos_ + chart_h + 3, "Helvetica 6");
            idx++;
        }
        y_pos_ += chart_h + 20;
    }

    void generate(const std::string& output_path) {
        surface_ = cairo_pdf_surface_create(output_path.c_str(), PAGE_WIDTH, PAGE_HEIGHT);
        cr_ = cairo_create(surface_);

        // Cover page
        new_page();
        y_pos_ = PAGE_HEIGHT / 2 - 30;
        set_color(cr_, DARK_BLUE);
        draw_text(cr_, title_, MARGIN, y_pos_, "Helvetica Bold 24");
        y_pos_ += 35;
        set_color(cr_, MEDIUM_GRAY);
        std::string subtitle = "Prepared by " + author_ + " | " + get_month_year();
        draw_text(cr_, subtitle, MARGIN, y_pos_, "Helvetica 12");
        y_pos_ += 25;
        draw_paragraph("Comprehensive analysis of organizational performance metrics "
                        "and strategic insights for the current fiscal year.");
        draw_header_footer();

        // TOC page
        new_page();
        draw_heading("Table of Contents", 0);
        double toc_y_start = y_pos_;
        draw_header_footer();

        // Section 1
        new_page();
        draw_heading("1. Executive Summary", 0);
        draw_paragraph("Revenue increased by 15.3% year-over-year driven by expansion "
                        "into new markets and improved retention rates.");
        draw_heading("1.1 Key Performance Indicators", 1);
        draw_table(
            {"Metric", "Q1", "Q2", "Q3", "Q4", "YoY"},
            {{"Revenue ($M)", "12.4", "14.1", "15.8", "17.2", "+15.3%"},
             {"Net Profit ($M)", "2.1", "2.5", "2.9", "3.4", "+22.1%"},
             {"Customers (K)", "45.2", "48.7", "52.1", "56.8", "+12.4%"},
             {"Satisfaction", "87.3", "89.1", "91.5", "93.2", "+5.9pp"}}
        );
        draw_header_footer();

        // Section 2
        new_page();
        draw_heading("2. Financial Analysis", 0);
        std::map<std::string, double> revenue = {
            {"Engineering", 18.5}, {"Sales", 24.3}, {"Marketing", 8.7},
            {"Operations", 5.2}, {"Support", 3.8}
        };
        draw_bar_chart(revenue, "Revenue by Department ($M)");

        draw_heading("2.1 Expense Breakdown", 1);
        draw_table(
            {"Category", "Budget ($M)", "Actual ($M)", "Variance"},
            {{"Salaries", "18.5", "17.9", "-3.2%"},
             {"Cloud", "6.2", "6.8", "+9.7%"},
             {"Marketing", "5.1", "4.7", "-7.8%"},
             {"R&D", "4.8", "5.2", "+8.3%"}}
        );
        draw_header_footer();

        // Section 3
        new_page();
        draw_heading("3. Growth Trends", 0);
        std::map<std::string, double> monthly = {
            {"Jan", 10.2}, {"Feb", 10.8}, {"Mar", 11.1}, {"Apr", 12.4},
            {"May", 12.9}, {"Jun", 13.5}, {"Jul", 14.1}, {"Aug", 14.8}
        };
        draw_bar_chart(monthly, "Monthly Revenue Trend ($M)");
        draw_header_footer();

        // Section 4
        new_page();
        draw_heading("4. Regional Performance", 0);
        draw_table(
            {"Region", "Revenue", "Growth", "Share"},
            {{"N. America", "$28.4M", "+12.1%", "34.2%"},
             {"Europe", "$19.7M", "+18.5%", "23.7%"},
             {"Asia-Pac", "$15.3M", "+25.3%", "18.4%"},
             {"LATAM", "$8.9M", "+31.2%", "10.7%"}}
        );
        std::map<std::string, double> regional = {
            {"N.America", 28.4}, {"Europe", 19.7}, {"Asia-Pac", 15.3},
            {"LATAM", 8.9}, {"Africa", 5.2}
        };
        draw_bar_chart(regional, "Revenue by Region ($M)");
        draw_header_footer();

        // Section 5
        new_page();
        draw_heading("5. Conclusions & Recommendations", 0);
        draw_paragraph("1. Increase investment in high-growth markets.");
        draw_paragraph("2. Continue cost optimization through automation.");
        draw_paragraph("3. Expand product portfolio.");
        draw_paragraph("4. Invest in employee development.");
        draw_paragraph("5. Establish data analytics team.");
        draw_header_footer();

        cairo_surface_finish(surface_);
        std::cout << "Report generated: " << output_path << std::endl;
    }

private:
    std::string title_;
    std::string author_;
    int page_count_;
    double y_pos_;
    cairo_surface_t* surface_;
    cairo_t* cr_;
    std::vector<TocEntry> toc_entries_;
};

int main(int argc, char* argv[]) {
    std::string output = "report.pdf";
    std::string title = "Annual Performance Report";
    std::string author = "PDF Report Generator";

    for (int i = 1; i < argc; i++) {
        std::string arg = argv[i];
        if ((arg == "-o" || arg == "--output") && i + 1 < argc) output = argv[++i];
        else if ((arg == "-t" || arg == "--title") && i + 1 < argc) title = argv[++i];
        else if ((arg == "-a" || arg == "--author") && i + 1 < argc) author = argv[++i];
        else if (arg == "-h" || arg == "--help") {
            std::cout << "Usage: pdf_report_gen [-o output.pdf] [-t title] [-a author]" << std::endl;
            return 0;
        }
    }

    try {
        PdfReportGenerator gen(title, author);
        gen.generate(output);
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}
README.md
# PDF Report Generator (C++ - Trial 3)

Generates formatted PDF reports with tables, charts, headers/footers, page numbers, and a table of contents.

## Dependencies

- **Cairo** - 2D graphics library with PDF surface support
- **Pangomm** - C++ text layout and rendering library (Pango C++ bindings)

## Build

```bash
mkdir build && cd build
cmake ..
cmake --build .
```

## Usage

```bash
./pdf_report_gen -o report.pdf -t "Annual Performance Report" -a "Author Name"
```

### Options

| Flag | Description | Default |
|------|-------------|---------|
| `-o, --output` | Output PDF file path | `report.pdf` |
| `-t, --title` | Report title | `Annual Performance Report` |
| `-a, --author` | Report author name | `PDF Report Generator` |
| `-h, --help` | Show usage information | |

## Features

- Cairo PDF surface for direct PDF rendering
- Pango text layout with word wrapping
- Custom headers and footers with date and author
- Automatic page numbering
- Table of contents page
- Bar charts drawn directly via Cairo
- Styled data tables with alternating row colors
- Cover page with title and metadata