<commit_before>#include "dot.h"

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX_BUF_LEN 256
#define BUFFERS 3

static char buffer[BUFFERS][MAX_BUF_LEN];

/* Return a buffer which can be used to write string representation of
 * variable or symbol. Need to keep at most three alive in order to
 * print a full statement. Circulate using counter.
 */
static char *get_buffer(void)
{
    static int i;

    i = (i + 1) % BUFFERS;
    return buffer[i];
}

static const char *sanitize(const struct symbol *sym)
{
    const char *label;
    char *buffer;
    assert(sym->symtype == SYM_LABEL);

    label = sym_name(sym);
    buffer = get_buffer();
    strncpy(
        buffer,
        (label[0] == '.') ? label + 1 : label,
        MAX_BUF_LEN);
    return buffer;
}

static const char *escape(const struct symbol *sym)
{
    const char *label;
    char *buffer;
    assert(sym->symtype == SYM_LABEL);

    label = sym_name(sym);
    buffer = get_buffer();
    if (label[0] == '.') {
        buffer[0] = '\\';
        strncpy(buffer + 1, label, MAX_BUF_LEN - 1);
    } else {
        strncpy(buffer, label, MAX_BUF_LEN);
    }

    return buffer;
}

static char *vartostr(const struct var var)
{
    char *buffer = get_buffer();

    switch (var.kind) {
    case IMMEDIATE:
        switch (var.type->type) {
        case T_POINTER:
            if (var.symbol) {
                assert(var.symbol->symtype == SYM_STRING_VALUE);
                if (var.offset) {
                    sprintf(buffer, "$%s%s%d", sym_name(var.symbol),
                        (var.offset > 0) ? "+" : "", var.offset);
                } else {
                    sprintf(buffer, "$%s", sym_name(var.symbol));
                }
                break;
            }
        case T_UNSIGNED:
            sprintf(buffer, "%lu", var.imm.u);
            break;
        case T_SIGNED:
            sprintf(buffer, "%ld", var.imm.i);
            break;
        case T_REAL:
            if (is_float(var.type)) {
                sprintf(buffer, "%ff", var.imm.f);
            } else {
                sprintf(buffer, "%f", var.imm.d);
            }
            break;
        case T_ARRAY:
            assert(var.symbol && var.symbol->symtype == SYM_STRING_VALUE);
            sprintf(buffer, "\\\"%s\\\"", str_raw(var.symbol->string_value));
            break;
        default:
            assert(0);
        }
        break;
    case DIRECT:
        if (var.offset) {
            sprintf(buffer, "%s[%d]", sym_name(var.symbol), var.offset);    
        } else {
            sprintf(buffer, "%s", sym_name(var.symbol));
        }
        break;
    case ADDRESS:
        if (var.offset) {
            sprintf(buffer, "&%s[%d]", sym_name(var.symbol), var.offset);
        } else {
            sprintf(buffer, "&%s", sym_name(var.symbol));
        }
        break;
    case DEREF:
        if (!var.offset)
            sprintf(buffer, "*(%s)", sym_name(var.symbol));
        else if (var.offset > 0)
            sprintf(buffer, "*(%s + %d)", sym_name(var.symbol), var.offset);
        else
            sprintf(buffer, "*(%s - %d)", sym_name(var.symbol), -var.offset);
        break;
    }

    return buffer;
}

static void foutputnode(FILE *stream, struct block *node)
{
    int i;

    if (node->color == BLACK)
        return;

    node->color = BLACK;
    fprintf(stream, "\t%s [label=\"{ %s",<commit_msg>Print explicit meaning of ir variables in dot<commit_after>#include "dot.h"

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX_BUF_LEN 256
#define BUFFERS 3

static char buffer[BUFFERS][MAX_BUF_LEN];

/* Return a buffer which can be used to write string representation of
 * variable or symbol. Need to keep at most three alive in order to
 * print a full statement. Circulate using counter.
 */
static char *get_buffer(void)
{
    static int i;

    i = (i + 1) % BUFFERS;
    return buffer[i];
}

static const char *sanitize(const struct symbol *sym)
{
    const char *label;
    char *buffer;
    assert(sym->symtype == SYM_LABEL);

    label = sym_name(sym);
    buffer = get_buffer();
    strncpy(
        buffer,
        (label[0] == '.') ? label + 1 : label,
        MAX_BUF_LEN);
    return buffer;
}

static const char *escape(const struct symbol *sym)
{
    const char *label;
    char *buffer;
    assert(sym->symtype == SYM_LABEL);

    label = sym_name(sym);
    buffer = get_buffer();
    if (label[0] == '.') {
        buffer[0] = '\\';
        strncpy(buffer + 1, label, MAX_BUF_LEN - 1);
    } else {
        strncpy(buffer, label, MAX_BUF_LEN);
    }

    return buffer;
}

static char *vartostr(const struct var var)
{
    char *buffer = get_buffer();

    switch (var.kind) {
    case IMMEDIATE:
        switch (var.type->type) {
        case T_POINTER:
            if (var.symbol) {
                assert(var.symbol->symtype == SYM_STRING_VALUE);
                if (var.offset) {
                    sprintf(buffer, "$%s%s%d", sym_name(var.symbol),
                        (var.offset > 0) ? "+" : "", var.offset);
                } else {
                    sprintf(buffer, "$%s", sym_name(var.symbol));
                }
                break;
            }
        case T_UNSIGNED:
            sprintf(buffer, "%lu", var.imm.u);
            break;
        case T_SIGNED:
            sprintf(buffer, "%ld", var.imm.i);
            break;
        case T_REAL:
            if (is_float(var.type)) {
                sprintf(buffer, "%ff", var.imm.f);
            } else {
                sprintf(buffer, "%f", var.imm.d);
            }
            break;
        case T_ARRAY:
            assert(var.symbol && var.symbol->symtype == SYM_STRING_VALUE);
            sprintf(buffer, "\\\"%s\\\"", str_raw(var.symbol->string_value));
            break;
        default:
            assert(0);
        }
        break;
    case DIRECT:
        if (var.offset > 0) {
            sprintf(buffer, "*(&%s + %d)", sym_name(var.symbol), var.offset);
        } else if (var.offset < 0) {
            sprintf(buffer, "*(&%s - %d)", sym_name(var.symbol), -var.offset);
        } else {
            sprintf(buffer, "%s", sym_name(var.symbol));
        }
        break;
    case ADDRESS:
        if (var.offset > 0) {
            sprintf(buffer, "(&%s + %d)", sym_name(var.symbol), var.offset);
        } else if (var.offset < 0) {
            sprintf(buffer, "(&%s - %d)", sym_name(var.symbol), -var.offset);
        } else {
            sprintf(buffer, "&%s", sym_name(var.symbol));
        }
        break;
    case DEREF:
        if (var.offset > 0) {
            sprintf(buffer, "*(%s + %d)", sym_name(var.symbol), var.offset);
        } else if (var.offset < 0) {
            sprintf(buffer, "*(%s - %d)", sym_name(var.symbol), -var.offset);
        } else {
            sprintf(buffer, "*(%s)", sym_name(var.symbol));
        }
        break;
    }

    return buffer;
}

static void foutputnode(FILE *stream, struct block *node)
{
    int i;

    if (node->color == BLACK)
        return;

    node->color = BLACK;
    fprintf(stream, "\t%s [label=\"{ %s",
{'fraction_non_alphanumeric': 0.14969135802469136, 'fraction_numerical': 0.004629629629629629, 'mean_word_length': 1.8425039872408293, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '211152', 'n_tokens_mistral': 2342, 'n_tokens_neox': 2328, 'n_words': 553}