Bug fixes, error checking; V1 complete
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
minihex
|
||||||
12
README.md
12
README.md
@@ -1,3 +1,13 @@
|
|||||||
# minihex
|
# minihex
|
||||||
|
|
||||||
A minimalist, single-file hexadecimal editor written in C with no dependencies (except the standard library). The program tries to be as simple as possible. Many bugs exist.
|
A minimalist, single-file hexadecimal editor written in less than 100 lines of C with no dependencies (except the standard library). The program tries to be as simple as possible.
|
||||||
|
Other features might be added in the future.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
make
|
||||||
|
./minihex <file>
|
||||||
|
```
|
||||||
|
|
||||||
|
To get help with the commands, do not provide any filename.
|
||||||
|
|||||||
33
hex.c
33
hex.c
@@ -1,7 +1,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
// TODO: Stop appending garbage at file end
|
|
||||||
// TODO: Skip repeating lines
|
// TODO: Skip repeating lines
|
||||||
|
|
||||||
#define BYTES 1024
|
#define BYTES 1024
|
||||||
@@ -13,7 +12,6 @@ void print_hex(unsigned char* buf, int byteno, int pos)
|
|||||||
{
|
{
|
||||||
if (i % BYTES_PER_LINE == 0)
|
if (i % BYTES_PER_LINE == 0)
|
||||||
{
|
{
|
||||||
//printf("%03d: ", lineno);
|
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
printf(" ");
|
printf(" ");
|
||||||
@@ -26,7 +24,7 @@ void print_hex(unsigned char* buf, int byteno, int pos)
|
|||||||
puts("");
|
puts("");
|
||||||
// Here, we could print positions in hex but I prefer using integers. printf("%04X ", i);
|
// Here, we could print positions in hex but I prefer using integers. printf("%04X ", i);
|
||||||
if (pos == 0) printf("\x1b[1;34m%06d:\x1b[0m ", i);
|
if (pos == 0) printf("\x1b[1;34m%06d:\x1b[0m ", i);
|
||||||
else printf("\x1b[34m%06d:\x1b[0m ", pos);
|
else printf("\x1b[1;34m%06d:\x1b[0m ", pos);
|
||||||
}
|
}
|
||||||
printf("%.2X ", buf[i]);
|
printf("%.2X ", buf[i]);
|
||||||
}
|
}
|
||||||
@@ -58,7 +56,12 @@ int main(int argc, char** argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* f = fopen(argv[1], "r");
|
FILE* f = fopen(argv[1], "rb+");
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
printf("Error opening file %s\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
unsigned char buf[BYTES];
|
unsigned char buf[BYTES];
|
||||||
int byteno = fread(buf, 1, BYTES, f);
|
int byteno = fread(buf, 1, BYTES, f);
|
||||||
print_hex(buf, byteno, 0);
|
print_hex(buf, byteno, 0);
|
||||||
@@ -69,31 +72,25 @@ int main(int argc, char** argv)
|
|||||||
int loc;
|
int loc;
|
||||||
|
|
||||||
scanf(" %c", &cmd);
|
scanf(" %c", &cmd);
|
||||||
if (cmd == 'p' || cmd == 'P' || cmd == 'e' || cmd == 'E') scanf("%d", &loc);
|
if (cmd == 'p' || cmd == 'e') scanf("%d", &loc);
|
||||||
|
|
||||||
switch(cmd)
|
switch(cmd)
|
||||||
{
|
{
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'P':
|
|
||||||
print_hex(buf + loc, BYTES_PER_LINE, loc);
|
print_hex(buf + loc, BYTES_PER_LINE, loc);
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'E':
|
int value;
|
||||||
scanf("%hhx", buf + loc);
|
scanf("%x", &value);
|
||||||
|
if (loc < byteno) buf[loc] = (unsigned char)value;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
fseek(f, 0, SEEK_SET);
|
||||||
fclose(f);
|
fwrite(buf, 1, byteno, f);
|
||||||
f = fopen(argv[1], "w");
|
|
||||||
if (!f) {
|
|
||||||
perror("Error opening file for writing");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
fwrite(buf, 1, BYTES, f);
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
case 'Q':
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user