tagsvisit (aka `visit-tags-table') records the path to the tags file
which is lazily opened upon find-tags (aka M-.).  visit-tags-table
tries also to be smart and checks that the argument is really a file
using a stat + access dance, and loadtags() which will be called way
later just opens the stored path and parses it, trusting the checks
done before...

Let's make tagsvisit actually loading the tag file instead and
loadtags do the checks instead, which also happens to mirror what GNU
Emacs does.

ok?

Index: mg.1
===================================================================
RCS file: /cvs/src/usr.bin/mg/mg.1,v
retrieving revision 1.127
diff -u -p -r1.127 mg.1
--- mg.1        20 Oct 2022 18:59:24 -0000      1.127
+++ mg.1        28 Mar 2023 19:10:41 -0000
@@ -967,7 +967,7 @@ As it moves, convert any characters to u
 Toggle the visible bell.
 If this toggle is on, the modeline will flash.
 .It visit-tags-table
-Record name of the tags file to be used for subsequent find-tag.
+Load tags file to be used for subsequent find-tag.
 .It what-cursor-position
 Display a bunch of useful information about the current location of
 dot.
Index: tags.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/tags.c,v
retrieving revision 1.23
diff -u -p -r1.23 tags.c
--- tags.c      22 Mar 2023 22:09:37 -0000      1.23
+++ tags.c      28 Mar 2023 19:00:02 -0000
@@ -39,7 +39,6 @@ static void              unloadtags(void
 #define DEFAULTFN "tags"
 
 char *tagsfn = NULL;
-int  loaded  = FALSE;
 
 /* ctags(1) entries are parsed and maintained in a tree. */
 struct ctag {
@@ -74,7 +73,6 @@ int
 tagsvisit(int f, int n)
 {
        char fname[NFILEN], *bufp, *temp;
-       struct stat sb;
 
        if (getbufcwd(fname, sizeof(fname)) == FALSE)
                fname[0] = '\0';
@@ -90,20 +88,6 @@ tagsvisit(int f, int n)
        if (bufp == NULL)
                return (ABORT);
 
-       if (stat(bufp, &sb) == -1) {
-               dobeep();
-               ewprintf("stat: %s", strerror(errno));
-               return (FALSE);
-       } else if (S_ISREG(sb.st_mode) == 0) {
-               dobeep();
-               ewprintf("Not a regular file");
-               return (FALSE);
-       } else if (access(bufp, R_OK) == -1) {
-               dobeep();
-               ewprintf("Cannot access file %s", bufp);
-               return (FALSE);
-       }
-
        if (tagsfn == NULL) {
                if (bufp[0] == '\0') {
                        if ((tagsfn = strdup(fname)) == NULL) {
@@ -131,8 +115,14 @@ tagsvisit(int f, int n)
                        ewprintf("Starting a new list of tags table");
                        unloadtags();
                }
-               loaded = FALSE;
        }
+
+       if (loadtags(tagsfn) == FALSE) {
+               free(tagsfn);
+               tagsfn = NULL;
+               return (FALSE);
+       }
+
        return (TRUE);
 }
 
@@ -170,14 +160,6 @@ findtag(int f, int n)
        if (tagsfn == NULL)
                if ((ret = tagsvisit(f, n)) != TRUE)
                        return (ret);
-       if (!loaded) {
-               if (loadtags(tagsfn) == FALSE) {
-                       free(tagsfn);
-                       tagsfn = NULL;
-                       return (FALSE);
-               }
-               loaded = TRUE;
-       }
        return pushtag(tok);
 }
 
@@ -300,12 +282,25 @@ poptag(int f, int n)
 int
 loadtags(const char *fn)
 {
+       struct stat sb;
        char *l;
        FILE *fd;
 
        if ((fd = fopen(fn, "r")) == NULL) {
                dobeep();
                ewprintf("Unable to open tags file: %s", fn);
+               return (FALSE);
+       }
+       if (fstat(fileno(fd), &sb) == -1) {
+               dobeep();
+               ewprintf("fstat: %s", strerror(errno));
+               fclose(fd);
+               return (FALSE);
+       }
+       if (!S_ISREG(sb.st_mode)) {
+               dobeep();
+               ewprintf("Not a regular file");
+               fclose(fd);
                return (FALSE);
        }
        while ((l = fparseln(fd, NULL, NULL, "\\\\\0",

Reply via email to