summaryrefslogtreecommitdiff
path: root/menudriver.c
diff options
context:
space:
mode:
Diffstat (limited to 'menudriver.c')
-rw-r--r--menudriver.c112
1 files 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 <ctype.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
@@ -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");
-}