HTMLify

bitwise.c
Views: 16 | Author: abh
#include <ncurses.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

enum type {
    INT,
    FLOAT,
    CHAR,
};

union v_value {
    int _int;
    float _float;
    char _char;
    unsigned int bits;
};

struct variable {
    unsigned char type;
    union v_value value;
};

void draw_box(int y, int x, int width, int height);

void print_variable(struct variable var, int y, int x);

void set_bit(struct variable *var, int pos, bool value);

bool get_bit(struct variable var, int pos);

int get_bit_len(struct variable);

char *get_str_type(struct variable);

void print_bits_menuplater(struct variable, int);

int main() {
    int num, bitlen, hover_bit=0, c, key;
    struct variable var;

    
    srand(time(NULL));
    c = rand() % 3 + 1;

    switch (c) {
        case 1:
            var.type = INT;
            var.value._int = (int)rand();
            break;
        case 2:
            var.type = FLOAT;
            var.value._float = (float)rand();
            break;
        case 3:
            var.type = CHAR;
            var.value._char = (char)rand();
            break;
    }

    var.value.bits %= get_bit_len(var);
    bitlen = get_bit_len(var);

    initscr();
    keypad(stdscr, true);
    curs_set(0);

    while (true) {

        clear();
        print_variable(var, LINES / 2 - 2, COLS / 2 - 5);
        print_bits_menuplater(var, hover_bit);
        refresh();

        key = getch();

        switch (key) {
            case 259: // Up Key
            case 258: // Down Key
            case '\n':
            case ' ':
                set_bit(&var, hover_bit, !get_bit(var, hover_bit));
                break;
            
            case 260: // Left Key
                if (hover_bit < bitlen-1)
                    hover_bit++;
                break;
            
            case 261: // Right Key
                if (hover_bit > 0)
                    hover_bit--;
                break;

            case 'r':
                endwin();
                main();
                exit(0);

            case 27:
            case 'q':
                endwin();
                exit(0);
                break;
        }
    }

    endwin();
    return 0;
}

void draw_box(int y, int x, int width, int height) {
    int c_x = getcurx(stdscr), c_y = getcury(stdscr);
    int i;

    // draw top and bottm line
    for (i=0; i<width; i++) {
        if (i == 0) {
            mvaddch(y, x, '#');
            mvaddch(y+height-1, x, '#');
            addch('3');
        } else if (i == width-1) {
            mvaddch(y, x+i, '#');
            mvaddch(y+height-1, x+i, '#');
        } else {
            mvaddch(y, x+i, '-');
            mvaddch(y+height-1, x+i, '-');
        }
    }

    // draw left right lien
    for (i=1; i<height-1; i++) {
        mvaddch(y + i, x, '|');
        mvaddch(y + i, x + width - 1, '|');
    }
    
    move(c_y, c_x);
}

void print_variable(struct variable var, int y, int x) {
    char text_buffer[32];
    int box_width, widths[4];

    widths[0] = sprintf(text_buffer, "TYPE: %s", get_str_type(var));
    mvaddstr(y+1, x+2, text_buffer);
    
    switch (var.type) {
        case INT:
            widths[1] = sprintf(text_buffer, "REPR: %d", var.value._int);
            break;
        case FLOAT:
            widths[1] = sprintf(text_buffer, "REPR: %.6f", var.value._float);
            break;
        case CHAR:
            widths[1] = sprintf(text_buffer, "REPR: %c", var.value._char);
            break;
    }
    mvaddstr(y+2, x+2, text_buffer);
    
    widths[2] = sprintf(text_buffer, "BITS: %b", var.value.bits);
    mvaddstr(y+3, x+2, text_buffer);
    
    widths[3] = sprintf(text_buffer, "HEX:  %x", var.value.bits);
    mvaddstr(y+4, x+2, text_buffer);


    box_width = widths[0];
    for (int i=1; i<4; i++) {
        if (box_width < widths[i]) {
            box_width = widths[i];
        }
    }

    draw_box(y, x, box_width + 4, 6);
}

void set_bit(struct variable *var, int pos, bool value) {
    if (value) {
        var->value.bits |= (1 << pos);
    } else {
        var->value.bits &= ~(1 << pos);
    }
}

bool get_bit(struct variable var, int pos) {
    return var.value.bits & (1 << pos);
}

int get_bit_len(struct variable var) {
    switch (var.type) {
        case INT:
            return sizeof(int) * 8;
        case FLOAT:
            return sizeof(float) * 8;
        case CHAR:
            return sizeof(char) * 8;
    }
    return 0;
}

char* s_type[3] = {"INT", "FLOAT", "CHAR"};

char *get_str_type(struct variable var) {
    switch (var.type) {
        case INT:
            return s_type[0];
        case FLOAT:
            return s_type[1];
        case CHAR:
            return s_type[2];
    }
    return "";
}

void print_bits_menuplater(struct variable var, int hover_bit) {
    int bitlen = get_bit_len(var), y = LINES*0.80, x = COLS/2+bitlen;
    for (int i=0; i<bitlen; i++) {
        if (i == hover_bit)
            attron(A_REVERSE);
        mvaddch(y, x, get_bit(var, i) ? '1' : '0');
        if (i == hover_bit)
            attroff(A_REVERSE);
        x-=2;
    }
}

Comments