X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/tweak/blobdiff_plain/6e182d98f1e2191523a4a0b8532a73819d6dca8d..11825bd41d76804f440aa1511dda1ec20e566858:/main.c diff --git a/main.c b/main.c index 05df563..5e1dbfa 100644 --- a/main.c +++ b/main.c @@ -1,15 +1,6 @@ /* - * TODO before releasable quality: - * - * - Thorough testing. - * - * - Half decent build system. - * * TODO possibly after that: * - * - Need to handle >2Gb files! Up the `filesize' type to long - * long and use it everywhere. - * * - Multiple buffers, multiple on-screen windows. * + ^X^F to open new file * + ^X^R to open new file RO @@ -25,7 +16,16 @@ * rather than the current rather crap one; in particular * this enables pasting into the search string. * + er, how exactly do we deal with the problem of saving over - * a file which we're maintaining references to? + * a file which we're maintaining references to in another + * buffer? The _current_ buffer can at least be sorted out by + * replacing it with a fresh tree containing a single + * file-data block, but other buffers are in trouble. + * * if we can rely on Unix fd semantics, this isn't too + * bad; we can just keep the fd open on the original file, + * and then the data stays around even after we rename(2) + * our new version over the top. Disk space usage gets + * silly after a few iterations, but it's better than + * nothing. * * - Undo! * + this actually doesn't seem _too_ horrid. For a start, one @@ -38,12 +38,10 @@ * buf_delete_data (both must be cloned for an overwrite), * but I'm not convinced that simply cloning the entire thing * isn't a superior option. - * - * - Reverse search. - * + need to construct a reverse DFA. - * + probably should construct both every time, so that you can - * search forward for a thing and then immediately change - * your mind and search backward for the same thing. + * + this really starts to show up the distinction between a + * `buffer' and a bare tree. A buffer is something which has + * an undo chain attached; so, in particular, the cut buffer + * shouldn't be one. Sort that out. * * - In-place editing. * + this is an extra option when running in Fix mode. It @@ -52,7 +50,9 @@ * one, we simply seek within the original file and write out * all the pieces that have changed. * + Primarily useful for editing disk devices directly - * (yikes!). + * (yikes!), or other situations where you actually cannot + * create a fresh copy of the file and rename(2) it into + * place. * + I had intended to suggest that in Fix mode this would be * nice and easy, since every element of the buffer tree is * either a literal block (needs writing) or a from-file @@ -74,6 +74,8 @@ * _and_ when pasting a cut buffer _into_ one. */ +#include "tweak.h" + #include #include #include @@ -89,8 +91,6 @@ #include #endif -#include "tweak.h" - static void init(void); static void done(void); static void load_file (char *); @@ -100,8 +100,8 @@ char hex[256][3]; /* LUT: binary to hex, 1 byte */ char message[80]; -char decstatus[] = "%s TWEAK "VER": %-18.18s %s posn=%-10d size=%-10d"; -char hexstatus[] = "%s TWEAK "VER": %-18.18s %s posn=0x%-8X size=0x%-8X"; +char decstatus[] = "%s TWEAK "VER": %-18.18s %s posn=%-10"OFF"d size=%-10"OFF"d"; +char hexstatus[] = "%s TWEAK "VER": %-18.18s %s posn=0x%-8"OFF"X size=0x%-8"OFF"X"; char *statfmt = hexstatus; char last_char; @@ -118,12 +118,12 @@ int marking = FALSE; int modified = FALSE; int new_file = FALSE; /* shouldn't need initialisation - * but let's not take chances :-) */ -int width = 16; -int realoffset = 0, offset = 16; +fileoffset_t width = 16; +fileoffset_t realoffset = 0, offset = 16; int ascii_enabled = TRUE; -long file_size = 0, top_pos = 0, cur_pos = 0, mark_point = 0; +fileoffset_t file_size = 0, top_pos = 0, cur_pos = 0, mark_point = 0; int scrlines; @@ -131,7 +131,7 @@ int scrlines; * Main program */ int main(int argc, char **argv) { - int newoffset = -1, newwidth = -1; + fileoffset_t newoffset = -1, newwidth = -1; /* * Parse command line arguments @@ -167,10 +167,10 @@ int main(int argc, char **argv) { } switch (c) { case 'o': case 'O': - newoffset = strtol(value, NULL, 0); /* allow `0xXX' */ + newoffset = parse_num(value, NULL); break; case 'w': case 'W': - newwidth = strtol(value, NULL, 0); + newwidth = parse_num(value, NULL); break; } break; @@ -226,7 +226,7 @@ int main(int argc, char **argv) { void fix_offset(void) { if (3*width+11 > display_cols) { width = (display_cols-11) / 3; - sprintf (message, "Width reduced to %d to fit on the screen", width); + sprintf (message, "Width reduced to %"OFF"d to fit on the screen", width); } if (4*width+14 > display_cols) { ascii_enabled = FALSE; @@ -248,11 +248,11 @@ static void init(void) { display_setup(); - display_define_colour(COL_BUFFER, 7, 0); - display_define_colour(COL_SELECT, 0, 7); - display_define_colour(COL_STATUS, 11, 4); - display_define_colour(COL_ESCAPE, 9, 0); - display_define_colour(COL_INVALID, 11, 0); + display_define_colour(COL_BUFFER, -1, -1, FALSE); + display_define_colour(COL_SELECT, 0, 7, TRUE); + display_define_colour(COL_STATUS, 11, 4, TRUE); + display_define_colour(COL_ESCAPE, 9, 0, FALSE); + display_define_colour(COL_INVALID, 11, 0, FALSE); for (i=0; i<256; i++) { sprintf(hex[i], "%02X", i); @@ -276,7 +276,7 @@ static void load_file (char *fname) { file_size = 0; if ( (fp = fopen (fname, "rb")) ) { if (eager_mode) { - long len; + size_t len; static char buffer[4096]; filedata = buf_new_empty(); @@ -292,12 +292,12 @@ static void load_file (char *fname) { } fclose (fp); assert(file_size == buf_length(filedata)); - sprintf(message, "loaded %s (size %ld == 0x%lX).", + sprintf(message, "loaded %s (size %"OFF"d == 0x%"OFF"X).", fname, file_size, file_size); } else { filedata = buf_new_from_file(fp); file_size = buf_length(filedata); - sprintf(message, "opened %s (size %ld == 0x%lX).", + sprintf(message, "opened %s (size %"OFF"d == 0x%"OFF"X).", fname, file_size, file_size); } new_file = FALSE; @@ -318,7 +318,7 @@ static void load_file (char *fname) { */ int save_file (void) { FILE *fp; - long pos = 0; + fileoffset_t pos = 0; if (look_mode) return FALSE; /* do nothing! */ @@ -327,7 +327,7 @@ int save_file (void) { static char buffer[SAVE_BLKSIZ]; while (pos < file_size) { - long size = file_size - pos; + fileoffset_t size = file_size - pos; if (size > SAVE_BLKSIZ) size = SAVE_BLKSIZ; @@ -384,8 +384,9 @@ static int scrbuflines = 0; */ void draw_scr (void) { int scrsize, scroff, llen, i, j; - long currpos; - int marktop, markbot, mark; + fileoffset_t currpos; + fileoffset_t marktop, markbot; + int mark; char *p; unsigned char c, *q; char *linebuf; @@ -473,9 +474,10 @@ void draw_scr (void) { * requiring highlighting: a hex bit and an ascii * bit. */ - int localstart= (currposmarkbot ? markbot : - currpos+llen) - currpos; + fileoffset_t localstart= (currposmarkbot ? markbot : + currpos+llen) - currpos; localstart += width-llen; localstop += width-llen; display_write_chars(linebuf, 11+3*localstart); @@ -496,9 +498,11 @@ void draw_scr (void) { display_write_chars(linebuf+10+3*localstop, 2+3*width-3*localstop); } - } else + } else { + display_set_colour(COL_BUFFER); display_write_chars(linebuf, ascii_enabled ? 13+4*width : 10+3*width); + } } currpos += (currpos ? width : offset); display_clear_to_eol(); @@ -541,6 +545,9 @@ void draw_scr (void) { display_refresh (); } +volatile int safe_update, update_required; +void update (void); + /* * Get a string, in the "minibuffer". Return TRUE on success, FALSE * on break. Possibly syntax-highlight the entered string for @@ -563,9 +570,9 @@ int get_str (char *prompt, char *buf, int highlight) { p++; if (p=r || !isxdigit (*p)) + else if (p>=r || !isxdigit ((unsigned char)*p)) display_set_colour(COL_INVALID); - else if (p+1>=r || !isxdigit (p[1])) + else if (p+1>=r || !isxdigit ((unsigned char)p[1])) p++, display_set_colour(COL_INVALID); else p+=2, display_set_colour(COL_ESCAPE); @@ -633,7 +640,8 @@ int parse_quoted (char *buffer) { p++; if (*p == '\\') *q++ = *p++; - else if (p[1] && isxdigit(*p) && isxdigit(p[1])) { + else if (p[1] && isxdigit((unsigned char)*p) && + isxdigit((unsigned char)p[1])) { char buf[3]; buf[0] = *p++; buf[1] = *p++; @@ -664,8 +672,6 @@ void suspend(void) { #endif } -volatile int safe_update, update_required; - void update (void) { display_recheck_size(); fix_offset (); @@ -679,18 +685,18 @@ void schedule_update(void) { update_required = TRUE; } -long parse_num (char *buffer, int *error) { +fileoffset_t parse_num (char *buffer, int *error) { if (error) *error = FALSE; if (!buffer[strspn(buffer, "0123456789")]) { /* interpret as decimal */ - return atoi(buffer); + return ATOOFF(buffer); } else if (buffer[0]=='0' && (buffer[1]=='X' || buffer[1]=='x') && !buffer[2+strspn(buffer+2,"0123456789ABCDEFabcdef")]) { - return strtol(buffer+2, NULL, 16); + return STRTOOFF(buffer+2, NULL, 16); } else if (buffer[0]=='$' && !buffer[1+strspn(buffer+1,"0123456789ABCDEFabcdef")]) { - return strtol(buffer+1, NULL, 16); + return STRTOOFF(buffer+1, NULL, 16); } else { return 0; if (error)