Skip to content

Commit fe125a5

Browse files
authored
Add files via upload
1 parent dc802a6 commit fe125a5

File tree

4 files changed

+279
-0
lines changed

4 files changed

+279
-0
lines changed

error.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
void ok (char *src, char *message) {
2+
printf(txtG "[%s] " txtW "%s\n", src, message);
3+
}
4+
void error (char *src, char *message) {
5+
printf(txtR "[%s] " txtW "%s\n", src, message);
6+
exit(false);
7+
}

file.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
int file_read(char *filename, char *buffer, int max) {
2+
FILE *fp = fopen(filename, "rb");
3+
if ( fp == NULL ) { return false; }
4+
int cursor = 0; char c; while(cursor < max -1) {
5+
c = fgetc(fp);
6+
if( feof(fp) ) { break; }
7+
buffer[cursor] = c; cursor++;
8+
} fclose(fp); return cursor;
9+
}
10+
11+
int file_write (char *filename, char *buffer, int max) {
12+
FILE *fp = fopen(filename, "w+");
13+
if ( fp == NULL ) { return false; }
14+
int cursor; for (cursor = 0; cursor < max; cursor++) {
15+
if (fputc(buffer[cursor], fp) == EOF) { fclose(fp); return false; }
16+
} fclose(fp); return cursor;
17+
}

nex.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#include <stdio.h>
2+
#include <stdbool.h>
3+
#include <string.h>
4+
#include "tui.c"
5+
#include "error.c"
6+
#include "file.c"
7+
8+
int filelength; int buffersize;
9+
char *buffer;
10+
int edity = 0; int editp = 0; /* viewport y & file position */
11+
#define Height 16
12+
#define Columns 32 /* 3 chars: "00 " */
13+
#define ScreenFill Height*Columns
14+
#define version "nex version 0.0.0, https://Modula.dev"
15+
16+
void printCommand(char *keys, char *command) {
17+
int len = strlen(keys)+strlen(command);
18+
printf(txtK bxtW "%s" reset " %s ", keys, command);
19+
while(len<20) { printf(" "); len++; }
20+
}
21+
22+
char *insert(int position, char character){
23+
if (filelength+1 >= buffersize) { buffersize *= 2; buffer = realloc(buffer, buffersize); }
24+
memcpy(buffer+position+1, buffer+position, filelength-position);
25+
buffer[position] = character;
26+
return buffer;
27+
}
28+
29+
char *delete(int position){
30+
memcpy(buffer+position, buffer+position+1, filelength-position);
31+
if (filelength <= buffersize/2) { buffersize /= 2; buffer = realloc(buffer, buffersize); }
32+
return buffer;
33+
}
34+
35+
void save(char *filename) { file_write(filename, buffer, filelength); }
36+
37+
void refresh(){
38+
tui_clear(); printf(txtK bxtW version reset " File Size %d bytes (%x)\n", filelength, filelength);
39+
printf(txtP" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"reset);
40+
int c=(edity*Columns); int end=(edity*Columns)+ScreenFill;
41+
while(c < end && (c < filelength || c == 0)) {
42+
if (c % Columns == 0) { printf("\n"txtP"%04x "reset, c); }
43+
if (c == editp)
44+
{ printf(txtW bxtB blink""); }
45+
else {
46+
if (buffer[c]==0) { printf(txtR""); }
47+
else if (buffer[c]<32 || buffer[c]>126) { printf(txtG""); }
48+
}
49+
int h = (buffer[c] >> 4)&15;
50+
int l = buffer[c] & 15;
51+
printf("%1x%1x"reset" ", h, l);
52+
c++;
53+
} printf("\n");
54+
55+
tui_row(20);
56+
printCommand("Arrows", "Navigate");
57+
printCommand("Space", "Insert Zeros");
58+
printCommand("Z", "Delete character");
59+
printf("\n");
60+
printCommand("Ctrl+X", "Save");
61+
printCommand("Ctrl+C", "Quit");
62+
printf("\n");
63+
}
64+
65+
void quit(){
66+
terminal_reset_terminal_mode(&original_term);
67+
tui_clear(); tui_col(0); tui_row(0);
68+
exit(0);
69+
}
70+
71+
#define initsize 1024 * 1024 * 4
72+
int main(int argc, char **argv) {
73+
74+
if (argc != 2) { error("nex", "expects a filename as input"); }
75+
if (argv[1][0] == '-') {
76+
if (argv[1][1] == 'v') { ok("nex", version "\n"); }
77+
if (argv[1][1] == 'h') { ok("nex", "\n nex (filename) opens and edits a file in hex"); }
78+
}
79+
char *filename = argv[1];
80+
buffer = malloc(sizeof(char)*initsize); buffersize = initsize;
81+
filelength = file_read(filename, buffer, initsize);
82+
if (filelength == false) { filelength = 1; buffer[0] = 0; }
83+
84+
refresh();
85+
char charcode; bool changed = false; int fileheight = (filelength / Height);
86+
bool escaped = false; bool leftbracket = false; char value = 1;
87+
while(true) {
88+
charcode = tui_input();
89+
/*if (charcode != 0) { printf("[%x] ", (int)(charcode)); fflush(stdout); }*/
90+
if (charcode == 0) { usleep(1000); continue; }
91+
switch(charcode) {
92+
case 0: break;
93+
case CTRL_C: quit(); break;
94+
case CTRL_X: save(filename); break;
95+
case '\e': escaped = true; break;
96+
case '[': leftbracket = true; break;
97+
case ' ': buffer = insert(editp, '\0'); changed = true; filelength++; break;
98+
case 'z': if (filelength>0) { buffer = delete(editp); changed = true; filelength--; } break;
99+
case ARROW_LEFT:
100+
if (escaped == true && leftbracket == true )
101+
if (editp > 0) { editp--; } changed=true; break;
102+
case ARROW_RIGHT:
103+
if (escaped == true && leftbracket == true )
104+
editp++; if (editp >= filelength ) { editp = filelength-1; } changed=true; break;
105+
case ARROW_UP:
106+
if (escaped == true && leftbracket == true ) {
107+
if (editp > 31) { editp-=32;}
108+
if ( edity * Columns > editp ) { edity--; }
109+
changed=true;
110+
} break;
111+
case ARROW_DOWN:
112+
if (escaped == true && leftbracket == true ) {
113+
if (editp <= filelength - 32) { editp+=32;}
114+
if ((edity+Height-1) * Columns < editp ) { edity++; }
115+
changed=true;
116+
} break;
117+
case '0': if (value==1) {value = 0x00;} else { value += 0x00; buffer[editp]=value; value=1; editp++; changed=true;} break;
118+
case '1': if (value==1) {value = 0x10;} else { value += 0x01; buffer[editp]=value; value=1; editp++; changed=true;} break;
119+
case '2': if (value==1) {value = 0x20;} else { value += 0x02; buffer[editp]=value; value=1; editp++; changed=true;} break;
120+
case '3': if (value==1) {value = 0x30;} else { value += 0x03; buffer[editp]=value; value=1; editp++; changed=true;} break;
121+
case '4': if (value==1) {value = 0x40;} else { value += 0x04; buffer[editp]=value; value=1; editp++; changed=true;} break;
122+
case '5': if (value==1) {value = 0x50;} else { value += 0x05; buffer[editp]=value; value=1; editp++; changed=true;} break;
123+
case '6': if (value==1) {value = 0x60;} else { value += 0x06; buffer[editp]=value; value=1; editp++; changed=true;} break;
124+
case '7': if (value==1) {value = 0x70;} else { value += 0x07; buffer[editp]=value; value=1; editp++; changed=true;} break;
125+
case '8': if (value==1) {value = 0x80;} else { value += 0x08; buffer[editp]=value; value=1; editp++; changed=true;} break;
126+
case '9': if (value==1) {value = 0x90;} else { value += 0x09; buffer[editp]=value; value=1; editp++; changed=true;} break;
127+
case 'a': if (value==1) {value = 0xA0;} else { value += 0x0A; buffer[editp]=value; value=1; editp++; changed=true;} break;
128+
case 'b': if (value==1) {value = 0xB0;} else { value += 0x0B; buffer[editp]=value; value=1; editp++; changed=true;} break;
129+
case 'c': if (value==1) {value = 0xC0;} else { value += 0x0C; buffer[editp]=value; value=1; editp++; changed=true;} break;
130+
case 'd': if (value==1) {value = 0xD0;} else { value += 0x0D; buffer[editp]=value; value=1; editp++; changed=true;} break;
131+
case 'e': if (value==1) {value = 0xE0;} else { value += 0x0E; buffer[editp]=value; value=1; editp++; changed=true;} break;
132+
case 'f': if (value==1) {value = 0xF0;} else { value += 0x0F; buffer[editp]=value; value=1; editp++; changed=true;} break;
133+
default: escaped = false; leftbracket = false; changed = true;
134+
}
135+
if (changed == true) { refresh(); changed = false; }
136+
}
137+
}

tui.c

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// REQUIRES <stdio.h> <termios.h> <sys/select.h>
2+
3+
#ifndef TUI
4+
#define TUI
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <unistd.h>
8+
#include <termios.h>
9+
#include <sys/select.h>
10+
#endif
11+
12+
#define CTRL_C 3
13+
#define CTRL_D 4
14+
#define CTRL_Q 17
15+
#define CTRL_X 24
16+
#define CTRL_ESC 27
17+
#define BACKSPACE 8 /* '\b' */
18+
#define ARROW_LEFT 0x44
19+
#define ARROW_RIGHT 0x43
20+
#define ARROW_UP 0x41
21+
#define ARROW_DOWN 0x42
22+
23+
#define block_100 "█"
24+
#define block_75 "▓"
25+
#define block_50 "▒"
26+
#define block_25 "░"
27+
#define block_half "▄"
28+
#define block_check "▚"
29+
30+
#define txtK "\e[0;30m" // black
31+
#define txtR "\e[0;31m"
32+
#define txtG "\e[0;32m"
33+
#define txtY "\e[0;33m"
34+
#define txtB "\e[0;34m"
35+
#define txtP "\e[0;35m"
36+
#define txtC "\e[0;36m"
37+
#define txtW "\e[0;37m"
38+
#define bxtR "\e[41m"
39+
#define bxtG "\e[42m"
40+
#define bxtY "\e[43m"
41+
#define bxtB "\e[44m"
42+
#define bxtP "\e[45m"
43+
#define bxtC "\e[46m"
44+
#define bxtW "\e[47m"
45+
#define reset "\e[0m"
46+
#define blink "\e[5m"
47+
48+
void tui_return() { printf("\e[0F"); }
49+
void tui_row(int y) { printf("\e[H\e[%dB", y); }
50+
void tui_col(int x) { printf("\e[%dG", x); }
51+
void tui_position(int x, int y) { tui_row(y); tui_col(x); }
52+
void tui_clear() { tui_position(0,0); printf("\e[0J"); }
53+
54+
void tui_loadbar(int x, char *colorA, char *colorB) {
55+
printf("\n"); tui_col(0); printf(colorA);
56+
int i; for (i=0; i < 80; i++) {
57+
if ( i > x ) { printf(colorB); }
58+
printf(block_100);
59+
} printf(txtW "\n");
60+
}
61+
62+
// http://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html#user-input
63+
64+
/*
65+
void terminal_set_raw_mode() { struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &term); }
66+
void terminal_reset_terminal_mode(struct termios *original_term) { tcsetattr(STDIN_FILENO, TCSANOW, original_term); }
67+
char tui_input() {
68+
// Save the original terminal attributes
69+
struct termios original_term; tcgetattr(STDIN_FILENO, &original_term); terminal_set_raw_mode();
70+
71+
char ch = 0; struct timeval tv; fd_set readfds;
72+
FD_ZERO(&readfds); FD_SET(STDIN_FILENO, &readfds);
73+
tv.tv_sec = 0;
74+
tv.tv_usec = 0; // Set timeout to 0 for non-blocking
75+
76+
int retval = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv);
77+
if (retval == -1) { perror("select");
78+
} else if (retval) { read(STDIN_FILENO, &ch, 1); }
79+
terminal_reset_terminal_mode(&original_term);
80+
return ch;
81+
}
82+
*/
83+
void terminal_set_raw_mode() {
84+
struct termios term;
85+
tcgetattr(STDIN_FILENO, &term);
86+
term.c_lflag &= ~(ICANON | ECHO);
87+
tcsetattr(STDIN_FILENO, TCSANOW, &term);
88+
}
89+
90+
void terminal_reset_terminal_mode(struct termios *original_term) {
91+
tcsetattr(STDIN_FILENO, TCSANOW, original_term);
92+
}
93+
94+
struct termios original_term;
95+
char tui_input() {
96+
//struct termios original_term;
97+
tcgetattr(STDIN_FILENO, &original_term);
98+
terminal_set_raw_mode();
99+
100+
char ch = 0;
101+
struct timeval tv;
102+
fd_set readfds;
103+
104+
FD_ZERO(&readfds);
105+
FD_SET(STDIN_FILENO, &readfds);
106+
tv.tv_sec = 0;
107+
tv.tv_usec = 0;
108+
109+
int retval = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv);
110+
if (retval == -1) {
111+
perror("select");
112+
} else if (retval) {
113+
read(STDIN_FILENO, &ch, 1);
114+
}
115+
116+
terminal_reset_terminal_mode(&original_term);
117+
return ch;
118+
}

0 commit comments

Comments
 (0)