From 3d92b273bbbff3200478924f76455659a8638274 Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Mon, 28 Mar 2022 11:10:32 -0400 Subject: extract reading the next command into a function --- menudriver.c | 112 ++++++++++++++++++++++------------------------------------- 1 file changed, 42 insertions(+), 70 deletions(-) diff --git a/menudriver.c b/menudriver.c index 10e1c26..7447e73 100644 --- a/menudriver.c +++ b/menudriver.c @@ -9,6 +9,7 @@ * Revised to C11 standard and made 64bit compatible, January 2020 * *------------------------------------------------------------------------*/ +#include #include #include #include @@ -39,13 +40,35 @@ int fastback = 0; #endif void callshell(char[]); -void clrscr(void); void menudrive(const char *, const char *, char *); void pushlast(char *); void poplast(char *); void settings(const char *, const char *, int); int subdir(void); +static void clear_screen(void) +{ + system("tput clear"); +} + +static int read_next(size_t n, char buf[static n]) +{ + int c; + do { + c = getchar(); + } while (c == ' ' || c == '\t'); + ungetc(c, stdin); + + if (fgets(buf, n, stdin) == NULL) { + return 0; + } + + for (char *end = strchr(buf, '\n'); isspace(*end); end--) { + *end = '\0'; + } + return 1; +} + static void wait_for_return(void) { printf("[Hit return to continue]"); @@ -86,7 +109,7 @@ static void view_file(const char *viewer, const char *filename) return; } - clrscr(); + clear_screen(); char cmd[PATH_MAX]; @@ -156,8 +179,6 @@ void menudrive(const char *menuviewer, const char *viewer, char *dir) { char next[40] = "", last[40] = "."; - char *np; - int c; int bad = 0; if (chdir(dir) == -1) { @@ -168,7 +189,7 @@ void menudrive(const char *menuviewer, const char *viewer, char *dir) struct stat st; while (stat("contents", &st) == 0) { if (next[0] == '\0' || bad) { - clrscr(); + clear_screen(); /* invalid selection notified here, after clearing screen */ if (bad) { @@ -182,29 +203,9 @@ void menudrive(const char *menuviewer, const char *viewer, char *dir) view_menu(menuviewer, "contents"); printf("::please type selection number (or return to exit):"); - - /* read remainder of line into next, less leading white space */ - np = next; - c = getchar(); - while (c == ' ' || c == '\t') { - c = getchar(); - } - - while (c != '\n' && c != EOF) { - *np++ = c, c = getchar(); - } - - if (c == EOF) { - exit(0); + if (!read_next(sizeof(next), next)) { + exit(0); } - - /* remove trailing white space */ - if (next[0] != '!') { - while (np[-1] == ' ' || np[-1] == '\t') { - np--; - } - } - *np = '\0'; } if (next[0] == '\0') { @@ -238,7 +239,7 @@ void menudrive(const char *menuviewer, const char *viewer, char *dir) exit(1); } - if (chdir(next) == -1 || stat("contents", &st)) { + if (chdir(next) == -1 || stat("contents", &st) == -1) { bad = 1; chdir(hold); } else { @@ -249,38 +250,16 @@ void menudrive(const char *menuviewer, const char *viewer, char *dir) } else if (S_ISREG(st.st_mode)) { view_file(viewer, next); + strcpy(last, next); if (fastback) { - strcpy(last, next); next[0] = '\0'; } else { printf("::next selection (or return to go back to menu, or q to quit):"); - /* read remainder of line into next, less leading white space */ - strcpy(last, next); - np = next; - - c = getchar(); - while (c == ' ' || c == '\t') { - c = getchar(); - } - - while (c != '\n' && c != EOF) { - *np++ = c; - c = getchar(); - } - - if (c == EOF) { - exit(0); - } - - /* remove trailing white space */ - if (next[0] != '!') { - while (np[-1] == ' ' || np[-1] == '\t') { - np--; - } + if (!read_next(sizeof(next), next)) { + exit(0); } - *np = '\0'; } } @@ -324,7 +303,7 @@ void menudrive(const char *menuviewer, const char *viewer, char *dir) /* possibly a bug - can retreat above original dir, if parent contains a "contents" file - difficult to detect this in a general way, however */ -/* pathnames banned because +/* pathnames banned because (i) upward pathname will not return correctly if a directory (see above) (ii) direct selection of a grandchild directory leads to (a) returns via child, instead of directly @@ -385,7 +364,8 @@ prompt at bottom of a manual section before getting back to the contents\n\ page - to cure this set RETURNTOMENU=YES;\n\n"); */ -char lastvec[100], *lastp = lastvec + 1; +char lastvec[100]; +char *lastp = lastvec + 1; int giveup = 0; int subdir(void) @@ -395,17 +375,15 @@ int subdir(void) void pushlast(char *last) { - int n = strlen(last); - if (last[0] == '.') { - /* pathological cases */ - if (last[1] == '\0') { - return; - } else if (last[1] == '.' && last[2] == '\0') { - poplast(last); - return; - } + if (!strcmp(last, ".")) { + return; + } else if (!strcmp(last, "..")) { + poplast(last); + return; } + size_t n = strlen(last); + if (lastp + n > lastvec + 100) { /* overflow */ giveup = 1; return; @@ -431,9 +409,3 @@ void poplast(char *last) strcpy(last, ++lastp); } - -/* to clear screen */ -void clrscr(void) -{ - system("tput clear"); -} -- cgit v1.2.1