<commit_before>#include <stdio.h>
#include <unistd.h>
#include "popen_plus.h"

extern const char* __progname;

/* tab+name+blank */
static int                        max_assign_len = 0;
static int                        gdb_trap_flag  = 1;
static int                        gdb_running    = 0;
static struct popen_plus_process* p_fp;
static pthread_mutex_t            gdb_mutex = PTHREAD_MUTEX_INITIALIZER;
/* state machine states */
enum
{
    S_GET_ASSIGN = 0,
    S_GET_VALUE,
    S_GET_NAME,
    S_GET_ARRAY,
    S_LEFT_BRACE,
    S_MAX
};

/* token input type */
enum
{
    T_VALUE = 0,
    T_NAME,
    T_ASSIGN,
    T_LEFT_BRACE,
    T_RIGHT_BRACE,
    T_S_MAX,
    T_COMMA,
};

/* state transaction table */
static int state_table[S_MAX][T_S_MAX] =
{
    /* state           VALUE         NAME          ASSIGN       LEFT_B        RIGHT_B    */
    [S_GET_ASSIGN] = { -1,           -1,           S_GET_VALUE, -1,           -1         },
    [S_GET_VALUE ] = { S_GET_NAME,   -1,           -1,          S_LEFT_BRACE, -1         },
    [S_GET_NAME  ] = { -1,           S_GET_ASSIGN, -1,          S_LEFT_BRACE, S_GET_NAME },
    [S_GET_ARRAY ] = { S_GET_ARRAY,  S_GET_ARRAY,  -1,          -1,           S_GET_NAME },
    [S_LEFT_BRACE] = { S_GET_ARRAY,  S_GET_ASSIGN, -1,          S_LEFT_BRACE, -1         },
};

static void print_blanks(int num)
{
    while (num--)
    {
        printf(" ");
    }
}

static void print_name(char* name, int level)
{
    int len = level * 4;
    printf("\n");
    print_blanks(len);
    printf(".%s ", name);
    len += strlen(name) + 2;

    if (len > max_assign_len)
    {
        max_assign_len = len;
    }

    print_blanks(max_assign_len - len);
}

static int get_token(FILE* fp, char* token)
{
    int   ret = -1; /* no token */
    int   c;
    char* p_char  = token;
    int   is_done = 0;
    while (!is_done)
    {
        c = fgetc(fp);

        switch (c)
        {
        case ' ':
        case '\r':
        case '\n':
        case '\t':
            if (ret != -1)
            {
                is_done = 1;
            }
            break;

        case EOF:
            is_done = 1;
            break;

        case ',':
            if (ret == -1)
            {
                return T_COMMA;
            }

        case '{':
            if (ret == -1)
            {
                return T_LEFT_BRACE;
            }

        case '}':
            if (ret == -1)
            {
                return T_RIGHT_BRACE;
            }

        case '=':
            if (ret == -1)
            {
                return T_ASSIGN;
            }
            ungetc(c, fp);
            is_done = 1;
            break;

        default:
            *p_char++ = c;
            ret       = T_NAME;
        }
    }

    *p_char = '\0';

    if (ret == T_NAME && *token == '0')
    {
        ret = T_VALUE;
    }

    return ret;
}

static int get_type_name(FILE* fp, char* type_name)
{
    int         ret  = -1;
    char*       line = NULL, * p;
    size_t      len;
    const char* match_key = "type = ";

    int is_done = 0;
    while (!is_done)
    {
        if (getline(&line, &len, fp) < 0)
        {
            break;
        }

        if ((p = strstr(line, match_key)) != NULL)
        {
            ret     = 1;
            is_done = 1;
            p      += strlen(match_key);
            strcpy(type_name, p);
            type_name[strlen(type_name) - 1] = '\0';
        }
    }

    free(line);

    return ret;
}

static void stat_parsor(FILE* fp)
{
    int  state       = S_GET_VALUE;
    int  brace_level = 0;
    int  token_ret;
    char token[256];

    /* find the first '=' */
    while ((token_ret = getc(fp)) != '=' &&
           token_ret != EOF)
    {
    }

    int is_done = 0;
    while (!is_done)
    {
        token_ret = get_token(fp, token);

        if (token_ret == -1)
        {
            break;
        }

        if (token_ret == T_COMMA)
        {
            printf(",");
            continue;
        }

        switch (state)
        {
        case -1:
            printf("state machine got an error\n");
            is_done = 1;
            break;

        case S_GET_ASSIGN:
            printf("= ");
            break;

        case S_GET_VALUE:
            if (token_ret == T_LEFT_BRACE)
            {
                brace_level++;
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("{");
            }
            else if (token_ret == T_VALUE)
            {
                /* print the value */
                printf("%s", token);
                if (brace_level == 0)
                {
                    is_done = 1;
                    printf("\n");
                }
            }
            break;

        case S_GET_ARRAY:
            if (token_ret == T_RIGHT_BRACE)
            {
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("}");
                brace_level--;
                if (brace_level == 0)
                {
                    is_done = 1;
                    printf("\n");
                }
            }
            else if (token_ret == T_VALUE || token_ret == T_NAME)
            {
                /* print the value */
                printf(" %s", token);
            }
            break;

        case S_LEFT_BRACE:
            if (token_ret == T_LEFT_BRACE)
            {
                brace_level++;
                state = S_LEFT_BRACE;
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("{");
            }
            else if (token_ret == T_VALUE)
            {
                /* this is the first value! */
                printf("\n");
                print_blanks(brace_level * 4);
                printf("%s", token);
            }
            else if (token_ret == T_NAME)
            {
                /* this is a name */
                print_name(token, brace_level);
            }
            break;

        case S_GET_NAME:
            if (token_ret == T_NAME)
            {
                print_name(token, brace_level);
            }
            if (token_ret == T_LEFT_BRACE)
            {
                brace_level++;
                state = S_LEFT_BRACE;
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("{");
            }
            else if (token_ret == T_RIGHT_BRACE)
            {
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("}");
                brace_level--;
                if (brace_level == 0)
                {
                    is_done = 1;
                    printf("\n");
                }
            }
            break;
        }

        state = state_table[state][token_ret];
    }
}

static void gdb_print_exit()
{
    if (gdb_running != 0)
    {
        fprintf(p_fp->write_fp, "detach\nquit\n");
        popen_plus_close(p_fp);
        gdb_running = 0;
    }
}

static void gdb_print_init()
{
    char buf[256];

    atexit(gdb_print_exit);
    sprintf(buf, "gdb -n -q %s %d", __progname, getpid());
    p_fp = popen_plus(buf);
    if (p_fp == NULL)
    {
        printf("can't popen gdb\n");
        exit(1);
    }

    /* fprintf(p_fp->write_fp, "watch gdb_trap_flag\n"); */
    fprintf(p_fp->write_fp, "break %s:363\n", __FILE__);
    fprintf(p_fp->write_fp, "detach\n");
    gdb_running = 1;
}

void gdb_print(const char* name)
{
    char buf[256];
    int  old_stdout_fd;<commit_msg>hide gdb error message<commit_after>#include <stdio.h>
#include <unistd.h>
#include "popen_plus.h"

extern const char* __progname;

/* tab+name+blank */
static int                        max_assign_len = 0;
static int                        gdb_trap_flag  = 1;
static int                        gdb_running    = 0;
static struct popen_plus_process* p_fp;
static pthread_mutex_t            gdb_mutex = PTHREAD_MUTEX_INITIALIZER;
/* state machine states */
enum
{
    S_GET_ASSIGN = 0,
    S_GET_VALUE,
    S_GET_NAME,
    S_GET_ARRAY,
    S_LEFT_BRACE,
    S_MAX
};

/* token input type */
enum
{
    T_VALUE = 0,
    T_NAME,
    T_ASSIGN,
    T_LEFT_BRACE,
    T_RIGHT_BRACE,
    T_S_MAX,
    T_COMMA,
};

/* state transaction table */
static int state_table[S_MAX][T_S_MAX] =
{
    /* state           VALUE         NAME          ASSIGN       LEFT_B        RIGHT_B    */
    [S_GET_ASSIGN] = { -1,           -1,           S_GET_VALUE, -1,           -1         },
    [S_GET_VALUE ] = { S_GET_NAME,   -1,           -1,          S_LEFT_BRACE, -1         },
    [S_GET_NAME  ] = { -1,           S_GET_ASSIGN, -1,          S_LEFT_BRACE, S_GET_NAME },
    [S_GET_ARRAY ] = { S_GET_ARRAY,  S_GET_ARRAY,  -1,          -1,           S_GET_NAME },
    [S_LEFT_BRACE] = { S_GET_ARRAY,  S_GET_ASSIGN, -1,          S_LEFT_BRACE, -1         },
};

static void print_blanks(int num)
{
    while (num--)
    {
        printf(" ");
    }
}

static void print_name(char* name, int level)
{
    int len = level * 4;
    printf("\n");
    print_blanks(len);
    printf(".%s ", name);
    len += strlen(name) + 2;

    if (len > max_assign_len)
    {
        max_assign_len = len;
    }

    print_blanks(max_assign_len - len);
}

static int get_token(FILE* fp, char* token)
{
    int   ret = -1; /* no token */
    int   c;
    char* p_char  = token;
    int   is_done = 0;
    while (!is_done)
    {
        c = fgetc(fp);

        switch (c)
        {
        case ' ':
        case '\r':
        case '\n':
        case '\t':
            if (ret != -1)
            {
                is_done = 1;
            }
            break;

        case EOF:
            is_done = 1;
            break;

        case ',':
            if (ret == -1)
            {
                return T_COMMA;
            }

        case '{':
            if (ret == -1)
            {
                return T_LEFT_BRACE;
            }

        case '}':
            if (ret == -1)
            {
                return T_RIGHT_BRACE;
            }

        case '=':
            if (ret == -1)
            {
                return T_ASSIGN;
            }
            ungetc(c, fp);
            is_done = 1;
            break;

        default:
            *p_char++ = c;
            ret       = T_NAME;
        }
    }

    *p_char = '\0';

    if (ret == T_NAME && *token == '0')
    {
        ret = T_VALUE;
    }

    return ret;
}

static int get_type_name(FILE* fp, char* type_name)
{
    int         ret  = -1;
    char*       line = NULL, * p;
    size_t      len;
    const char* match_key = "type = ";

    int is_done = 0;
    while (!is_done)
    {
        if (getline(&line, &len, fp) < 0)
        {
            break;
        }

        if ((p = strstr(line, match_key)) != NULL)
        {
            ret     = 1;
            is_done = 1;
            p      += strlen(match_key);
            strcpy(type_name, p);
            type_name[strlen(type_name) - 1] = '\0';
        }
    }

    free(line);

    return ret;
}

static void stat_parsor(FILE* fp)
{
    int  state       = S_GET_VALUE;
    int  brace_level = 0;
    int  token_ret;
    char token[256];

    /* find the first '=' */
    while ((token_ret = getc(fp)) != '=' &&
           token_ret != EOF)
    {
    }

    int is_done = 0;
    while (!is_done)
    {
        token_ret = get_token(fp, token);

        if (token_ret == -1)
        {
            break;
        }

        if (token_ret == T_COMMA)
        {
            printf(",");
            continue;
        }

        switch (state)
        {
        case -1:
            printf("state machine got an error\n");
            is_done = 1;
            break;

        case S_GET_ASSIGN:
            printf("= ");
            break;

        case S_GET_VALUE:
            if (token_ret == T_LEFT_BRACE)
            {
                brace_level++;
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("{");
            }
            else if (token_ret == T_VALUE)
            {
                /* print the value */
                printf("%s", token);
                if (brace_level == 0)
                {
                    is_done = 1;
                    printf("\n");
                }
            }
            break;

        case S_GET_ARRAY:
            if (token_ret == T_RIGHT_BRACE)
            {
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("}");
                brace_level--;
                if (brace_level == 0)
                {
                    is_done = 1;
                    printf("\n");
                }
            }
            else if (token_ret == T_VALUE || token_ret == T_NAME)
            {
                /* print the value */
                printf(" %s", token);
            }
            break;

        case S_LEFT_BRACE:
            if (token_ret == T_LEFT_BRACE)
            {
                brace_level++;
                state = S_LEFT_BRACE;
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("{");
            }
            else if (token_ret == T_VALUE)
            {
                /* this is the first value! */
                printf("\n");
                print_blanks(brace_level * 4);
                printf("%s", token);
            }
            else if (token_ret == T_NAME)
            {
                /* this is a name */
                print_name(token, brace_level);
            }
            break;

        case S_GET_NAME:
            if (token_ret == T_NAME)
            {
                print_name(token, brace_level);
            }
            if (token_ret == T_LEFT_BRACE)
            {
                brace_level++;
                state = S_LEFT_BRACE;
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("{");
            }
            else if (token_ret == T_RIGHT_BRACE)
            {
                printf("\n");
                print_blanks(4 * (brace_level - 1));
                printf("}");
                brace_level--;
                if (brace_level == 0)
                {
                    is_done = 1;
                    printf("\n");
                }
            }
            break;
        }

        state = state_table[state][token_ret];
    }
}

static void gdb_print_exit()
{
    if (gdb_running != 0)
    {
        fprintf(p_fp->write_fp, "detach\nquit\n");
        popen_plus_close(p_fp);
        gdb_running = 0;
    }
}

static void gdb_print_init()
{
    char buf[256];

    atexit(gdb_print_exit);
    sprintf(buf, "gdb -n -q %s %d 2>/dev/null", __progname, getpid());
    p_fp = popen_plus(buf);
    if (p_fp == NULL)
    {
        printf("can't popen gdb\n");
        exit(1);
    }

    /* fprintf(p_fp->write_fp, "watch gdb_trap_flag\n"); */
    fprintf(p_fp->write_fp, "break %s:363\n", __FILE__);
    fprintf(p_fp->write_fp, "detach\n");
    gdb_running = 1;
}

void gdb_print(const char* name)
{
    char buf[256];
    int  old_stdout_fd;
{'fraction_non_alphanumeric': 0.12206727909589585, 'fraction_numerical': 0.01024387020025114, 'mean_word_length': 1.10254272613589, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 18, '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': '2424491', 'n_tokens_mistral': 5117, 'n_tokens_neox': 4854, 'n_words': 1011}