Compare commits

...

5 Commits

Author SHA1 Message Date
Mid Favila 4d0d726e1d Fix a segmentation violation when zep isn't given a file to edit. 2022-09-03 10:59:59 -04:00
Hugh Barney 1d945d0390 removed some blank lines to make code count 700 lines 2017-04-15 23:18:37 +01:00
Hugh Barney a763bd8c65 further line count reduction by removing some whitespace 2017-04-14 15:29:09 +01:00
Hugh Barney 1d1d1b5ef0 zep 1.5 removed redundant header files 2017-04-14 14:37:56 +01:00
Hugh Barney 6f8d31577e Zep 1.4 small code reductions 2017-04-14 14:10:42 +01:00
1 changed files with 49 additions and 109 deletions

158
zep.c
View File

@ -1,24 +1,17 @@
/* zep.c, Zep Emacs, Public Domain, Hugh Barney, 2017, Derived from: Anthony's Editor January 93 */ /* zep.c, Zep Emacs, Public Domain, Hugh Barney, 2017, Derived from: Anthony's Editor January 93 */
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <assert.h> #include <assert.h>
#include <curses.h> #include <curses.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <termios.h>
#define E_NAME "zep" #define E_NAME "zep"
#define E_VERSION "v1.3" #define E_VERSION "v1.6"
#define E_LABEL "Zep:" #define E_LABEL "Zep:"
#define B_MODIFIED 0x01 /* modified buffer */
#define MSGLINE (LINES-1) #define MSGLINE (LINES-1)
#define CHUNK 8096L #define CHUNK 8096L
#define K_BUFFER_LENGTH 256 #define K_BUFFER_LENGTH 256
@ -52,15 +45,14 @@ typedef struct buffer_t
int b_row; /* cursor row */ int b_row; /* cursor row */
int b_col; /* cursor col */ int b_col; /* cursor col */
char b_fname[MAX_FNAME + 1]; /* filename */ char b_fname[MAX_FNAME + 1]; /* filename */
char b_flags; /* buffer flags */ char b_modified; /* was modified */
} buffer_t; } buffer_t;
/* /*
* Some compilers define size_t as a unsigned 16 bit number while * Some compilers define size_t as a unsigned 16 bit number while point_t and
* point_t and off_t might be defined as a signed 32 bit number. * off_t might be defined as a signed 32 bit number. malloc(), realloc(),
* malloc(), realloc(), fread(), and fwrite() take size_t parameters, * fread(), and fwrite() take size_t parameters, which means there will be some
* which means there will be some size limits because size_t is too * size limits because size_t is too small of a type.
* small of a type.
*/ */
#define MAX_SIZE_T ((unsigned long) (size_t) ~0) #define MAX_SIZE_T ((unsigned long) (size_t) ~0)
@ -68,7 +60,6 @@ int done;
char_t *input; char_t *input;
int msgflag; int msgflag;
char msgline[TEMPBUF]; char msgline[TEMPBUF];
char temp[TEMPBUF];
keymap_t *key_return; keymap_t *key_return;
keymap_t *key_map; keymap_t *key_map;
buffer_t *curbp; buffer_t *curbp;
@ -80,11 +71,11 @@ buffer_t* new_buffer()
{ {
buffer_t *bp = (buffer_t *)malloc(sizeof(buffer_t)); buffer_t *bp = (buffer_t *)malloc(sizeof(buffer_t));
assert(bp != NULL); assert(bp != NULL);
bp->b_point = 0; bp->b_point = 0;
bp->b_mark = NOMARK;
bp->b_page = 0; bp->b_page = 0;
bp->b_epage = 0; bp->b_epage = 0;
bp->b_flags = 0; bp->b_modified = 0;
bp->b_buf = NULL; bp->b_buf = NULL;
bp->b_ebuf = NULL; bp->b_ebuf = NULL;
bp->b_gap = NULL; bp->b_gap = NULL;
@ -97,21 +88,20 @@ buffer_t* new_buffer()
void fatal(char *msg) void fatal(char *msg)
{ {
move(LINES-1, 0);
refresh();
noraw(); noraw();
endwin(); endwin();
printf("\n" E_NAME " " E_VERSION ": %s\n", msg); printf("\n" E_NAME " " E_VERSION ": %s\n", msg);
exit(1); exit(1);
} }
void msg(char *msg, ...) int msg(char *msg, ...)
{ {
va_list args; va_list args;
va_start(args, msg); va_start(args, msg);
(void)vsprintf(msgline, msg, args); (void)vsprintf(msgline, msg, args);
va_end(args); va_end(args);
msgflag = TRUE; msgflag = TRUE;
return FALSE;
} }
/* Given a buffer offset, convert it to a pointer into the buffer */ /* Given a buffer offset, convert it to a pointer into the buffer */
@ -133,11 +123,9 @@ int growgap(buffer_t *bp, point_t n)
{ {
char_t *new; char_t *new;
point_t buflen, newlen, xgap, xegap; point_t buflen, newlen, xgap, xegap;
assert(bp->b_buf <= bp->b_gap); assert(bp->b_buf <= bp->b_gap);
assert(bp->b_gap <= bp->b_egap); assert(bp->b_gap <= bp->b_egap);
assert(bp->b_egap <= bp->b_ebuf); assert(bp->b_egap <= bp->b_ebuf);
xgap = bp->b_gap - bp->b_buf; xgap = bp->b_gap - bp->b_buf;
xegap = bp->b_egap - bp->b_buf; xegap = bp->b_egap - bp->b_buf;
buflen = bp->b_ebuf - bp->b_buf; buflen = bp->b_ebuf - bp->b_buf;
@ -147,24 +135,16 @@ int growgap(buffer_t *bp, point_t n)
newlen = buflen + n * sizeof (char_t); newlen = buflen + n * sizeof (char_t);
if (buflen == 0) { if (buflen == 0) {
if (newlen < 0 || MAX_SIZE_T < newlen) fatal("Failed to allocate required memory.\n"); if (newlen < 0 || MAX_SIZE_T < newlen) fatal("Failed to allocate required memory");
new = (char_t*) malloc((size_t) newlen); new = (char_t*) malloc((size_t) newlen);
if (new == NULL) fatal("Failed to allocate required memory.\n"); if (new == NULL) fatal("Failed to allocate required memory");
} else { } else {
if (newlen < 0 || MAX_SIZE_T < newlen) { if (newlen < 0 || MAX_SIZE_T < newlen) return msg("Failed to allocate required memory");
msg("Failed to allocate required memory");
return (FALSE);
}
new = (char_t*) realloc(bp->b_buf, (size_t) newlen); new = (char_t*) realloc(bp->b_buf, (size_t) newlen);
if (new == NULL) { if (new == NULL) return msg("Failed to allocate required memory");
msg("Failed to allocate required memory"); /* Report non-fatal error. */
return (FALSE);
}
} }
/* Relocate pointers in new buffer and append the new /* Relocate pointers in new buffer and append the new extension to the end of the gap */
* extension to the end of the gap.
*/
bp->b_buf = new; bp->b_buf = new;
bp->b_gap = bp->b_buf + xgap; bp->b_gap = bp->b_buf + xgap;
bp->b_ebuf = bp->b_buf + buflen; bp->b_ebuf = bp->b_buf + buflen;
@ -197,7 +177,6 @@ void save()
{ {
FILE *fp; FILE *fp;
point_t length; point_t length;
fp = fopen(curbp->b_fname, "w"); fp = fopen(curbp->b_fname, "w");
if (fp == NULL) msg("Failed to open file \"%s\".", curbp->b_fname); if (fp == NULL) msg("Failed to open file \"%s\".", curbp->b_fname);
(void) movegap(curbp, (point_t) 0); (void) movegap(curbp, (point_t) 0);
@ -205,39 +184,25 @@ void save()
if (fwrite(curbp->b_egap, sizeof (char), (size_t) length, fp) != length) if (fwrite(curbp->b_egap, sizeof (char), (size_t) length, fp) != length)
msg("Failed to write file \"%s\".", curbp->b_fname); msg("Failed to write file \"%s\".", curbp->b_fname);
fclose(fp); fclose(fp);
curbp->b_flags &= ~B_MODIFIED; curbp->b_modified = 0;
msg("File \"%s\" %ld bytes saved.", curbp->b_fname, pos(curbp, curbp->b_ebuf)); msg("File \"%s\" %ld bytes saved.", curbp->b_fname, pos(curbp, curbp->b_ebuf));
} }
/* reads file into buffer at point */ /* reads file into buffer at point */
int insert_file(char *fn, int modflag) int insert_file(char *fn)
{ {
FILE *fp; FILE *fp;
size_t len; size_t len;
struct stat sb; struct stat sb;
if (stat(fn, &sb) < 0) { if (stat(fn, &sb) < 0) return msg("Failed to find file \"%s\".", fn);
msg("Failed to find file \"%s\".", fn); if (MAX_SIZE_T < sb.st_size) return msg("File \"%s\" is too big to load.", fn);
return (FALSE);
}
if (MAX_SIZE_T < sb.st_size) {
msg("File \"%s\" is too big to load.", fn);
return (FALSE);
}
if (curbp->b_egap - curbp->b_gap < sb.st_size * sizeof (char_t) && !growgap(curbp, sb.st_size)) if (curbp->b_egap - curbp->b_gap < sb.st_size * sizeof (char_t) && !growgap(curbp, sb.st_size))
return (FALSE); return (FALSE);
if ((fp = fopen(fn, "r")) == NULL) { if ((fp = fopen(fn, "r")) == NULL) return msg("Failed to open file \"%s\".", fn);
msg("Failed to open file \"%s\".", fn);
return (FALSE);
}
curbp->b_point = movegap(curbp, curbp->b_point); curbp->b_point = movegap(curbp, curbp->b_point);
curbp->b_gap += len = fread(curbp->b_gap, sizeof (char), (size_t) sb.st_size, fp); curbp->b_gap += len = fread(curbp->b_gap, sizeof (char), (size_t) sb.st_size, fp);
if (fclose(fp) != 0) return msg("Failed to close file \"%s\".", fn);
if (fclose(fp) != 0) {
msg("Failed to close file \"%s\".", fn);
return (FALSE);
}
curbp->b_flags &= (modflag ? B_MODIFIED : ~B_MODIFIED);
msg("File \"%s\" %ld bytes read.", fn, len); msg("File \"%s\" %ld bytes read.", fn, len);
return (TRUE); return (TRUE);
} }
@ -248,7 +213,6 @@ char_t *get_key(keymap_t *keys, keymap_t **key_return)
int submatch; int submatch;
static char_t buffer[K_BUFFER_LENGTH]; static char_t buffer[K_BUFFER_LENGTH];
static char_t *record = buffer; static char_t *record = buffer;
*key_return = NULL; *key_return = NULL;
/* if recorded bytes remain, return next recorded byte. */ /* if recorded bytes remain, return next recorded byte. */
@ -256,19 +220,16 @@ char_t *get_key(keymap_t *keys, keymap_t **key_return)
*key_return = NULL; *key_return = NULL;
return record++; return record++;
} }
/* reset record buffer. */
record = buffer; record = buffer; /* reset record buffer. */
do { do {
assert(K_BUFFER_LENGTH > record - buffer); assert(K_BUFFER_LENGTH > record - buffer);
/* read and record one byte. */ *record++ = (unsigned)getch(); /* read and record one byte. */
*record++ = (unsigned)getch();
*record = '\0'; *record = '\0';
/* if recorded bytes match any multi-byte sequence... */ /* if recorded bytes match any multi-byte sequence... */
for (k = keys, submatch = 0; k->key_bytes != NULL; ++k) { for (k = keys, submatch = 0; k->key_bytes != NULL; ++k) {
char_t *p, *q; char_t *p, *q;
for (p = buffer, q = (char_t *)k->key_bytes; *p == *q; ++p, ++q) { for (p = buffer, q = (char_t *)k->key_bytes; *p == *q; ++p, ++q) {
/* an exact match */ /* an exact match */
if (*q == '\0' && *p == '\0') { if (*q == '\0' && *p == '\0') {
@ -279,9 +240,7 @@ char_t *get_key(keymap_t *keys, keymap_t **key_return)
} }
} }
/* record bytes match part of a command sequence */ /* record bytes match part of a command sequence */
if (*p == '\0' && *q != '\0') { if (*p == '\0' && *q != '\0') submatch = 1;
submatch = 1;
}
} }
} while (submatch); } while (submatch);
/* nothing matched, return recorded bytes. */ /* nothing matched, return recorded bytes. */
@ -310,7 +269,7 @@ point_t segstart(buffer_t *bp, point_t start, point_t finish)
p = ptr(bp, scan); p = ptr(bp, scan);
if (*p == '\n') { if (*p == '\n') {
c = 0; c = 0;
start = scan+1; start = scan + 1;
} else if (COLS <= c) { } else if (COLS <= c) {
c = 0; c = 0;
start = scan; start = scan;
@ -330,11 +289,9 @@ point_t segnext(buffer_t *bp, point_t start, point_t finish)
point_t scan = segstart(bp, start, finish); point_t scan = segstart(bp, start, finish);
for (;;) { for (;;) {
p = ptr(bp, scan); p = ptr(bp, scan);
if (bp->b_ebuf <= p || COLS <= c) if (bp->b_ebuf <= p || COLS <= c) break;
break;
++scan; ++scan;
if (*p == '\n') if (*p == '\n') break;
break;
c += *p == '\t' ? 8 - (c & 7) : 1; c += *p == '\t' ? 8 - (c & 7) : 1;
} }
return (p < bp->b_ebuf ? scan : pos(bp, bp->b_ebuf)); return (p < bp->b_ebuf ? scan : pos(bp, bp->b_ebuf));
@ -353,10 +310,7 @@ point_t upup(buffer_t *bp, point_t off)
} }
/* Move down one screen line */ /* Move down one screen line */
point_t dndn(buffer_t *bp, point_t off) point_t dndn(buffer_t *bp, point_t off) { return (segnext(bp, lnstart(bp,off), off)); }
{
return (segnext(bp, lnstart(bp,off), off));
}
/* Return the offset of a column on the specified line */ /* Return the offset of a column on the specified line */
point_t lncolumn(buffer_t *bp, point_t offset, int column) point_t lncolumn(buffer_t *bp, point_t offset, int column)
@ -373,14 +327,14 @@ point_t lncolumn(buffer_t *bp, point_t offset, int column)
void modeline(buffer_t *bp) void modeline(buffer_t *bp)
{ {
int i; int i;
char temp[TEMPBUF];
char mch; char mch;
standout(); standout();
move(bp->w_top + bp->w_rows, 0); move(bp->w_top + bp->w_rows, 0);
mch = ((bp->b_flags & B_MODIFIED) ? '*' : '='); mch = bp->b_modified ? '*' : '=';
sprintf(temp, "=%c " E_LABEL " == %s ", mch, bp->b_fname); sprintf(temp, "=%c " E_LABEL " == %s ", mch, bp->b_fname);
addstr(temp); addstr(temp);
for (i = strlen(temp) + 1; i <= COLS; i++) for (i = strlen(temp) + 1; i <= COLS; i++)
addch('='); addch('=');
standend(); standend();
@ -450,8 +404,7 @@ void display()
} }
if (*p == '\n' || COLS <= j) { if (*p == '\n' || COLS <= j) {
j -= COLS; j -= COLS;
if (j < 0) if (j < 0) j = 0;
j = 0;
++i; ++i;
} }
++bp->b_epage; ++bp->b_epage;
@ -509,7 +462,7 @@ void insert()
curbp->b_point = movegap(curbp, curbp->b_point); curbp->b_point = movegap(curbp, curbp->b_point);
*curbp->b_gap++ = *input == '\r' ? '\n' : *input; *curbp->b_gap++ = *input == '\r' ? '\n' : *input;
curbp->b_point = pos(curbp, curbp->b_egap); curbp->b_point = pos(curbp, curbp->b_egap);
curbp->b_flags |= B_MODIFIED; curbp->b_modified = 1;
} }
void backsp() void backsp()
@ -517,7 +470,7 @@ void backsp()
curbp->b_point = movegap(curbp, curbp->b_point); curbp->b_point = movegap(curbp, curbp->b_point);
if (curbp->b_buf < curbp->b_gap) { if (curbp->b_buf < curbp->b_gap) {
--curbp->b_gap; --curbp->b_gap;
curbp->b_flags |= B_MODIFIED; curbp->b_modified = 1;
} }
curbp->b_point = pos(curbp, curbp->b_egap); curbp->b_point = pos(curbp, curbp->b_egap);
} }
@ -527,7 +480,7 @@ void delete()
curbp->b_point = movegap(curbp, curbp->b_point); curbp->b_point = movegap(curbp, curbp->b_point);
if (curbp->b_egap < curbp->b_ebuf) { if (curbp->b_egap < curbp->b_ebuf) {
curbp->b_point = pos(curbp, ++curbp->b_egap); curbp->b_point = pos(curbp, ++curbp->b_egap);
curbp->b_flags |= B_MODIFIED; curbp->b_modified = 1;
} }
} }
@ -564,7 +517,7 @@ void copy_cut(int cut)
if (cut) { if (cut) {
curbp->b_egap += nscrap; /* if cut expand gap down */ curbp->b_egap += nscrap; /* if cut expand gap down */
curbp->b_point = pos(curbp, curbp->b_egap); /* set point to after region */ curbp->b_point = pos(curbp, curbp->b_egap); /* set point to after region */
curbp->b_flags |= B_MODIFIED; curbp->b_modified = 1;
msg("%ld bytes cut.", nscrap); msg("%ld bytes cut.", nscrap);
} else { } else {
msg("%ld bytes copied.", nscrap); msg("%ld bytes copied.", nscrap);
@ -582,7 +535,7 @@ void paste()
memcpy(curbp->b_gap, scrap, nscrap * sizeof (char_t)); memcpy(curbp->b_gap, scrap, nscrap * sizeof (char_t));
curbp->b_gap += nscrap; curbp->b_gap += nscrap;
curbp->b_point = pos(curbp, curbp->b_egap); curbp->b_point = pos(curbp, curbp->b_egap);
curbp->b_flags |= B_MODIFIED; curbp->b_modified = 1;
} }
} }
@ -607,17 +560,13 @@ point_t search_forward(buffer_t *bp, point_t start_p, char *stext)
point_t p,pp; point_t p,pp;
char* s; char* s;
if (0 == strlen(stext)) if (0 == strlen(stext)) return start_p;
return start_p;
for (p=start_p; p < end_p; p++) { for (p=start_p; p < end_p; p++) {
for (s=stext, pp=p; *s == *(ptr(bp, pp)) && *s !='\0' && pp < end_p; s++, pp++) for (s=stext, pp=p; *s == *(ptr(bp, pp)) && *s !='\0' && pp < end_p; s++, pp++)
; ;
if (*s == '\0') return pp;
if (*s == '\0')
return pp;
} }
return -1; return -1;
} }
@ -627,7 +576,6 @@ void search()
int c; int c;
point_t o_point = curbp->b_point; point_t o_point = curbp->b_point;
point_t found; point_t found;
searchtext[0] = '\0'; searchtext[0] = '\0';
msg("Search: %s", searchtext); msg("Search: %s", searchtext);
dispmsg(); dispmsg();
@ -719,44 +667,36 @@ keymap_t keymap[] = {
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 2) fatal("usage: " E_NAME " filename\n"); if(argc != 2)
{
printf("usage: %s filename\n", argv[0]);
exit(1);
}
initscr(); initscr();
raw(); raw();
noecho(); noecho();
curbp = new_buffer(); curbp = new_buffer();
(void)insert_file(argv[1], FALSE); (void)insert_file(argv[1]);
/* Save filename irregardless of load() success. */ strncpy(curbp->b_fname, argv[1], MAX_FNAME); /* save filename regardless */
strncpy(curbp->b_fname, argv[1], MAX_FNAME);
curbp->b_fname[MAX_FNAME] = '\0'; /* force truncation */ curbp->b_fname[MAX_FNAME] = '\0'; /* force truncation */
if (!growgap(curbp, CHUNK)) fatal("Failed to allocate required memory.\n"); if (!growgap(curbp, CHUNK)) fatal("Failed to allocate required memory.\n");
key_map = keymap; key_map = keymap;
while (!done) { while (!done) {
display(); display();
input = get_key(key_map, &key_return); input = get_key(key_map, &key_return);
if (key_return != NULL) { if (key_return != NULL) {
(key_return->func)(); (key_return->func)();
} else { } else {
/* allow TAB and NEWLINE, any other control char is 'Not Bound' */ if (*input > 31 || *input == 10 || *input == 9) /* allow TAB, NEWLINE and other control char is Not Bound */
if (*input > 31 || *input == 10 || *input == 9)
insert(); insert();
else { else
fflush(stdin);
msg("Not bound"); msg("Not bound");
}
} }
} }
if (scrap != NULL) free(scrap); if (scrap != NULL) free(scrap);
if (curbp != NULL) free(curbp); if (curbp != NULL) free(curbp);
move(MSGLINE, 0);
refresh();
noraw(); noraw();
endwin(); endwin();
return 0; return 0;