Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make Begin cleanup of the make parser: separate out ...



details:   https://anonhg.NetBSD.org/src/rev/8e140f196ca8
branches:  trunk
changeset: 760050:8e140f196ca8
user:      dholland <dholland%NetBSD.org@localhost>
date:      Sat Dec 25 04:57:07 2010 +0000

description:
Begin cleanup of the make parser: separate out the logic for reading files
from the parsing goo. This will now use mmap for reading if it works and
fall back to read only for pipes and such. Step 1 of a cleanup program
proposed without objection on tech-toolchain.

diffstat:

 usr.bin/make/for.c     |    9 +-
 usr.bin/make/main.c    |    8 +-
 usr.bin/make/nonints.h |    4 +-
 usr.bin/make/parse.c   |  368 +++++++++++++++++++++++++++++++++++-------------
 4 files changed, 276 insertions(+), 113 deletions(-)

diffs (truncated from 608 to 300 lines):

diff -r bb4f8a2f9667 -r 8e140f196ca8 usr.bin/make/for.c
--- a/usr.bin/make/for.c        Sat Dec 25 03:29:08 2010 +0000
+++ b/usr.bin/make/for.c        Sat Dec 25 04:57:07 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: for.c,v 1.47 2010/02/06 20:37:13 dholland Exp $        */
+/*     $NetBSD: for.c,v 1.48 2010/12/25 04:57:07 dholland Exp $        */
 
 /*
  * Copyright (c) 1992, The Regents of the University of California.
@@ -30,14 +30,14 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: for.c,v 1.47 2010/02/06 20:37:13 dholland Exp $";
+static char rcsid[] = "$NetBSD: for.c,v 1.48 2010/12/25 04:57:07 dholland Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)for.c      8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: for.c,v 1.47 2010/02/06 20:37:13 dholland Exp $");
+__RCSID("$NetBSD: for.c,v 1.48 2010/12/25 04:57:07 dholland Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -366,7 +366,7 @@
 }
 
 static char *
-For_Iterate(void *v_arg)
+For_Iterate(void *v_arg, size_t *ret_len)
 {
     For *arg = v_arg;
     int i, len;
@@ -451,6 +451,7 @@
     arg->sub_next += strlist_num(&arg->vars);
 
     arg->parse_buf = cp;
+    *ret_len = strlen(cp);
     return cp;
 }
 
diff -r bb4f8a2f9667 -r 8e140f196ca8 usr.bin/make/main.c
--- a/usr.bin/make/main.c       Sat Dec 25 03:29:08 2010 +0000
+++ b/usr.bin/make/main.c       Sat Dec 25 04:57:07 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: main.c,v 1.192 2010/12/13 01:48:50 dholland Exp $      */
+/*     $NetBSD: main.c,v 1.193 2010/12/25 04:57:07 dholland Exp $      */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.192 2010/12/13 01:48:50 dholland Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.193 2010/12/25 04:57:07 dholland Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
@@ -81,7 +81,7 @@
 #if 0
 static char sccsid[] = "@(#)main.c     8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: main.c,v 1.192 2010/12/13 01:48:50 dholland Exp $");
+__RCSID("$NetBSD: main.c,v 1.193 2010/12/25 04:57:07 dholland Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -1307,7 +1307,7 @@
        char *name, *path = bmake_malloc(len);
 
        if (!strcmp(fname, "-")) {
-               Parse_File("(stdin)", dup(fileno(stdin)));
+               Parse_File(NULL /*stdin*/, -1);
                Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
        } else {
                /* if we've chdir'd, rebuild the path name */
diff -r bb4f8a2f9667 -r 8e140f196ca8 usr.bin/make/nonints.h
--- a/usr.bin/make/nonints.h    Sat Dec 25 03:29:08 2010 +0000
+++ b/usr.bin/make/nonints.h    Sat Dec 25 04:57:07 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nonints.h,v 1.61 2010/12/09 22:30:17 sjg Exp $ */
+/*     $NetBSD: nonints.h,v 1.62 2010/12/25 04:57:07 dholland Exp $    */
 
 /*-
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -136,7 +136,7 @@
 void Parse_File(const char *, int);
 void Parse_Init(void);
 void Parse_End(void);
-void Parse_SetInput(const char *, int, int, char *(*)(void *), void *);
+void Parse_SetInput(const char *, int, int, char *(*)(void *, size_t *), void *);
 Lst Parse_MainName(void);
 
 /* str.c */
diff -r bb4f8a2f9667 -r 8e140f196ca8 usr.bin/make/parse.c
--- a/usr.bin/make/parse.c      Sat Dec 25 03:29:08 2010 +0000
+++ b/usr.bin/make/parse.c      Sat Dec 25 04:57:07 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: parse.c,v 1.169 2010/12/13 05:01:56 dholland Exp $     */
+/*     $NetBSD: parse.c,v 1.170 2010/12/25 04:57:07 dholland Exp $     */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: parse.c,v 1.169 2010/12/13 05:01:56 dholland Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.170 2010/12/25 04:57:07 dholland Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)parse.c    8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: parse.c,v 1.169 2010/12/13 05:01:56 dholland Exp $");
+__RCSID("$NetBSD: parse.c,v 1.170 2010/12/25 04:57:07 dholland Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -123,12 +123,19 @@
  *     Parse_MainName              Returns a Lst of the main target to create.
  */
 
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
 #include <stdio.h>
 
+#ifndef MAP_COPY
+#define MAP_COPY MAP_PRIVATE
+#endif
+
 #include "make.h"
 #include "hash.h"
 #include "dir.h"
@@ -146,17 +153,15 @@
     const char      *fname;         /* name of file */
     int             lineno;         /* current line number in file */
     int             first_lineno;   /* line number of start of text */
-    int             fd;             /* the open file */
     int             cond_depth;     /* 'if' nesting when file opened */
     char            *P_str;         /* point to base of string buffer */
     char            *P_ptr;         /* point to next char of string buffer */
     char            *P_end;         /* point to the end of string buffer */
-    int             P_buflen;       /* current size of file buffer */
-    char            *(*nextbuf)(void *); /* Function to get more data */
+    char            *(*nextbuf)(void *, size_t *); /* Function to get more data */
     void            *nextbuf_arg;   /* Opaque arg for nextbuf() */
+    struct loadedfile *lf;          /* loadedfile object, if any */
 } IFile;
 
-#define IFILE_BUFLEN 0x8000
 
 /*
  * These values are returned by ParseEOF to tell Parse_File whether to
@@ -359,7 +364,198 @@
 static void ParseMark(GNode *);
 
 ////////////////////////////////////////////////////////////
-// code
+// file loader
+
+struct loadedfile {
+       const char *path;               /* name, for error reports */
+       char *buf;                      /* contents buffer */
+       size_t len;                     /* length of contents */
+       size_t maplen;                  /* length of mmap area, or 0 */
+       Boolean used;                   /* XXX: have we used the data yet */
+};
+
+/*
+ * Constructor/destructor for loadedfile
+ */
+static struct loadedfile *
+loadedfile_create(const char *path)
+{
+       struct loadedfile *lf;
+
+       lf = bmake_malloc(sizeof(*lf));
+       lf->path = (path == NULL ? "(stdin)" : path);
+       lf->buf = NULL;
+       lf->len = 0;
+       lf->maplen = 0;
+       lf->used = FALSE;
+       return lf;
+}
+
+static void
+loadedfile_destroy(struct loadedfile *lf)
+{
+       if (lf->buf != NULL) {
+               if (lf->maplen > 0) {
+                       munmap(lf->buf, lf->maplen);
+               } else {
+                       free(lf->buf);
+               }
+       }
+       free(lf);
+}
+
+/*
+ * nextbuf() operation for loadedfile, as needed by the weird and twisted
+ * logic below. Once that's cleaned up, we can get rid of lf->used...
+ */
+static char *
+loadedfile_nextbuf(void *x, size_t *len)
+{
+       struct loadedfile *lf = x;
+
+       if (lf->used) {
+               return NULL;
+       }
+       lf->used = TRUE;
+       *len = lf->len;
+       return lf->buf;
+}
+
+/*
+ * Try to get the size of a file.
+ */
+static ReturnStatus
+load_getsize(int fd, size_t *ret)
+{
+       struct stat st;
+
+       if (fstat(fd, &st) < 0) {
+               return FAILURE;
+       }
+
+       if (!S_ISREG(st.st_mode)) {
+               return FAILURE;
+       }
+
+       /*
+        * st_size is an off_t, which is 64 bits signed; *ret is
+        * size_t, which might be 32 bits unsigned or 64 bits
+        * unsigned. Rather than being elaborate, just punt on
+        * files that are more than 2^31 bytes. We should never
+        * see a makefile that size in practice...
+        *
+        * While we're at it reject negative sizes too, just in case.
+        */
+       if (st.st_size < 0 || st.st_size > 0x7fffffff) {
+               return FAILURE;
+       }
+
+       *ret = (size_t) st.st_size;
+       return SUCCESS;
+}
+
+/*
+ * Read in a file.
+ *
+ * Until the path search logic can be moved under here instead of
+ * being in the caller in another source file, we need to have the fd
+ * passed in already open. Bleh.
+ *
+ * If the path is NULL use stdin and (to insure against fd leaks)
+ * assert that the caller passed in -1.
+ */
+static struct loadedfile *
+loadfile(const char *path, int fd)
+{
+       struct loadedfile *lf;
+       long pagesize;
+       ssize_t result;
+       size_t bufpos;
+
+       lf = loadedfile_create(path);
+
+       if (path == NULL) {
+               assert(fd == -1);
+               fd = STDIN_FILENO;
+       } else {
+#if 0 /* notyet */
+               fd = open(path, O_RDONLY);
+               if (fd < 0) {
+                       ...
+                       Error("%s: %s", path, strerror(errno));
+                       exit(1);
+               }
+#endif
+       }
+
+       if (load_getsize(fd, &lf->len) == SUCCESS) {
+               /* found a size, try mmap */
+               pagesize = sysconf(_SC_PAGESIZE);
+               if (pagesize <= 0) {
+                       pagesize = 0x1000;
+               }
+               /* round size up to a page */
+               lf->maplen = pagesize * ((lf->len + pagesize - 1)/pagesize);



Home | Main Index | Thread Index | Old Index