Looks good and works for me, ok nicm.

On Sun, Jul 10, 2011 at 09:42:28AM -0400, Todd C. Miller wrote:
> This time for terminfo.  These are the same basic changes I've made
> to getcap.c but applied to getinfo.c.
> 
> Before:
> $ /usr/bin/time cap_mkdb -i -f obj/terminfo obj/terminfo.src
>         6.57 real         5.51 user         0.93 sys
> 
> After:
> $ /usr/bin/time cap_mkdb -i -f obj/terminfo obj/terminfo.src
>         4.03 real         3.62 user         0.24 sys
> 
>  - todd
> 
> Index: usr.bin/cap_mkdb/getinfo.c
> ===================================================================
> RCS file: /home/cvs/openbsd/src/usr.bin/cap_mkdb/getinfo.c,v
> retrieving revision 1.17
> diff -u -r1.17 getinfo.c
> --- usr.bin/cap_mkdb/getinfo.c        4 Jul 2011 21:34:54 -0000       1.17
> +++ usr.bin/cap_mkdb/getinfo.c        9 Jul 2011 20:51:11 -0000
> @@ -50,7 +50,7 @@
>  #define TCERR        (char)1
>  #define      SHADOW  (char)2
>  
> -static int    getent(char **, u_int *, char **, int, char *, int);
> +static int    getent(char **, u_int *, char **, FILE *, char *, int);
>  static char  *igetcap(char *, char *, int);
>  static int    igetmatch(char *, char *);
>  static int    igetclose(void);
> @@ -111,8 +111,8 @@
>  }
>  
>  /*
> - * Getent implements the functions of igetent.  If fd is non-negative,
> - * *db_array has already been opened and fd is the open file descriptor.  We
> + * Getent implements the functions of igetent.  If fp is non-NULL,
> + * *db_array has already been opened and fp is the open file descriptor.  We
>   * do this to save time and avoid using up file descriptors for use=
>   * recursions.
>   *
> @@ -129,7 +129,7 @@
>   *     MAX_RECURSION.
>   */
>  static int
> -getent(char **cap, u_int *len, char **db_array, int fd, char *name, int 
> depth)
> +getent(char **cap, u_int *len, char **db_array, FILE *fp, char *name, int 
> depth)
>  {
>       char *r_end, *rp, **db_p;
>       int myfd, eof, foundit;
> @@ -143,6 +143,21 @@
>       if (depth > MAX_RECURSION)
>               return (-3);
>  
> +        /*
> +         * If no name we better have a record in cap
> +         */
> +        if (depth == 0 && name == NULL) {
> +                if ((record = malloc(*len + 1 + BFRAG)) == NULL)
> +                        return (-2);
> +                memcpy(record, *cap, *len);
> +                myfd = 0;
> +                db_p = db_array;
> +                rp = record + *len + 1;
> +                r_end = rp + BFRAG;
> +             *rp = '\0';
> +                goto exp_use;
> +        }
> +
>       /*
>        * Allocate first chunk of memory.
>        */
> @@ -154,10 +169,10 @@
>       foundit = 0;
>       rp = NULL;
>       myfd = -1;
> +
>       /*
>        * Loop through database array until finding the record.
>        */
> -
>       for (db_p = db_array; *db_p != NULL; db_p++) {
>               eof = 0;
>  
> @@ -165,12 +180,12 @@
>                * Open database if not already open.
>                */
>  
> -             if (fd >= 0) {
> -                     (void)lseek(fd, (off_t)0, SEEK_SET);
> +             if (fp != NULL) {
> +                     (void)fseek(fp, 0L, SEEK_SET);
>                       myfd = 0;
>               } else {
> -                     fd = open(*db_p, O_RDONLY, 0);
> -                     if (fd < 0) {
> +                     fp = fopen(*db_p, "r");
> +                     if (fp == NULL) {
>                               /* No error on unfound file. */
>                               continue;
>                       }
> @@ -197,26 +212,24 @@
>               for (;;) {
>  
>                       /*
> -                      * Read in a line implementing (\, newline)
> -                      * line continuation.
> +                      * Read in a record implementing line continuation.
>                        */
>                       rp = record;
>                       for (;;) {
>                               if (bp >= b_end) {
> -                                     int n;
> +                                     size_t n;
>  
> -                                     n = read(fd, buf, sizeof(buf));
> -                                     if (n <= 0) {
> +                                     n = fread(buf, 1, sizeof(buf), fp);
> +                                     if (n == 0) {
> +                                             eof = feof(fp);
>                                               if (myfd)
> -                                                     (void)close(fd);
> -                                             if (n < 0) {
> -                                                     free(record);
> -                                                     return (-2);
> -                                             } else {
> -                                                     fd = -1;
> -                                                     eof = 1;
> +                                                     (void)fclose(fp);
> +                                             if (eof) {
> +                                                     fp = NULL;
>                                                       break;
>                                               }
> +                                             free(record);
> +                                             return (-2);
>                                       }
>                                       b_end = buf+n;
>                                       bp = buf;
> @@ -225,20 +238,19 @@
>                               c = *bp++;
>                               if (c == '\n') {
>                                       if (bp >= b_end) {
> -                                             int n;
> +                                             size_t n;
>  
> -                                             n = read(fd, buf, sizeof(buf));
> -                                             if (n <= 0) {
> +                                             n = fread(buf, 1, sizeof(buf), 
> fp);
> +                                             if (n == 0) {
> +                                                     eof = feof(fp);
>                                                       if (myfd)
> -                                                             (void)close(fd);
> -                                                     if (n < 0) {
> -                                                             free(record);
> -                                                             return (-2);
> -                                                     } else {
> -                                                             fd = -1;
> -                                                             eof = 1;
> +                                                             
> (void)fclose(fp);
> +                                                     if (eof) {
> +                                                             fp = NULL;
>                                                               break;
>                                                       }
> +                                                     free(record);
> +                                                     return (-2);
>                                               }
>                                               b_end = buf+n;
>                                               bp = buf;
> @@ -257,22 +269,22 @@
>                                * some more.
>                                */
>                               if (rp >= r_end) {
> -                                     u_int pos;
> +                                     size_t off;
>                                       size_t newsize;
>  
> -                                     pos = rp - record;
> +                                     off = rp - record;
>                                       newsize = r_end - record + BFRAG;
>                                       s = realloc(record, newsize);
>                                       if (s == NULL) {
>                                               free(record);
>                                               errno = ENOMEM;
>                                               if (myfd)
> -                                                     (void)close(fd);
> +                                                     (void)fclose(fp);
>                                               return (-2);
>                                       }
>                                       record = s;
>                                       r_end = record + newsize;
> -                                     rp = record + pos;
> +                                     rp = record + off;
>                               }
>                       }
>                       /* loop invariant lets us do this */
> @@ -312,7 +324,7 @@
>        * Got the capability record, but now we have to expand all use=name
>        * references in it ...
>        */
> -     {
> +exp_use: {
>               char *newicap;
>               int newilen;
>               u_int ilen;
> @@ -346,14 +358,14 @@
>                       tclen = s - tcstart;
>                       tcend = s;
>  
> -                     iret = getent(&icap, &ilen, db_p, fd, tc, depth+1);
> +                     iret = getent(&icap, &ilen, db_p, fp, tc, depth+1);
>                       newicap = icap;         /* Put into a register. */
>                       newilen = ilen;
>                       if (iret != 0) {
>                               /* an error */
>                               if (iret < -1) {
>                                       if (myfd)
> -                                             (void)close(fd);
> +                                             (void)fclose(fp);
>                                       free(record);
>                                       return (iret);
>                               }
> @@ -388,27 +400,27 @@
>                        */
>                       diff = newilen - tclen;
>                       if (diff >= r_end - rp) {
> -                             u_int pos, tcpos, tcposend;
> +                             size_t off, tcoff, tcoffend;
>                               size_t newsize;
>  
> -                             pos = rp - record;
> +                             off = rp - record;
>                               newsize = r_end - record + diff + BFRAG;
> -                             tcpos = tcstart - record;
> -                             tcposend = tcend - record;
> +                             tcoff = tcstart - record;
> +                             tcoffend = tcend - record;
>                               s = realloc(record, newsize);
>                               if (s == NULL) {
>                                       free(record);
>                                       errno = ENOMEM;
>                                       if (myfd)
> -                                             (void)close(fd);
> +                                             (void)fclose(fp);
>                                       free(icap);
>                                       return (-2);
>                               }
>                               record = s;
>                               r_end = record + newsize;
> -                             rp = record + pos;
> -                             tcstart = record + tcpos;
> -                             tcend = record + tcposend;
> +                             rp = record + off;
> +                             tcstart = record + tcoff;
> +                             tcend = record + tcoffend;
>                       }
>  
>                       /*
> @@ -433,7 +445,7 @@
>        * return capability, length and success.
>        */
>       if (myfd)
> -             (void)close(fd);
> +             (void)fclose(fp);
>       *len = rp - record - 1; /* don't count NUL */
>       if (r_end > rp) {
>               if ((s =
> @@ -515,107 +527,149 @@
>   * upon returning an entry with more remaining, and -1 if an error occurs.
>   */
>  int
> -igetnext(char **bp, char **db_array)
> +igetnext(char **cap, char **db_array)
>  {
> -     size_t len;
> -     int status, done;
> -     char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE];
> -     u_int dummy;
> +     int c, eof = 0, serrno, status = -1;
> +     char buf[BUFSIZ];
> +     char *b_end, *bp, *r_end, *rp;
> +     char *record = NULL;
> +     u_int len;
> +     off_t pos;
>  
>       if (dbp == NULL)
>               dbp = db_array;
>  
> -     if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) {
> -             (void)igetclose();
> -             return (-1);
> -     }
> +     if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL)
> +             goto done;
> +
> +     /*
> +      * Allocate first chunk of memory.
> +      */
> +     if ((record = malloc(BFRAG)) == NULL)
> +             goto done;
> +     r_end = record + BFRAG;
> +
> +     /*
> +      * Find the next capability record
> +      */
> +     /*
> +      * Loop invariants:
> +      *      There is always room for one more character in record.
> +      *      R_end always points just past end of record.
> +      *      Rp always points just past last character in record.
> +      *      B_end always points just past last character in buf.
> +      *      Bp always points at next character in buf.
> +      */
> +     b_end = buf;
> +     bp = buf;
>       for (;;) {
> -             line = fgetln(pfp, &len);
> -             if (line == NULL) {
> -                     if (ferror(pfp)) {
> -                             (void)igetclose();
> -                             return (-1);
> -                     } else {
> -                             (void)fclose(pfp);
> -                             pfp = NULL;
> -                             if (*++dbp == NULL) {
> -                                     (void)igetclose();
> -                                     return (0);
> -                             } else if ((pfp =
> -                                 fopen(*dbp, "r")) == NULL) {
> -                                     (void)igetclose();
> -                                     return (-1);
> -                             } else
> -                                     continue;
> +             /*
> +              * If encountered EOF check next file.
> +              */
> +             if (eof) {
> +                     (void)fclose(pfp);
> +                     pfp = NULL;
> +                     if (*++dbp == NULL) {
> +                             status = 0;
> +                             break;
>                       }
> -             } else
> -                     line[len - 1] = '\0';/* XXX - assumes newline */
> -             if (len == 1) {
> -                     slash = 0;
> -                     continue;
> -             }
> -             if (isspace(*line) ||
> -                 *line == ',' || *line == '#' || slash) {
> -                     if (line[len - 2] == '\\')
> -                             slash = 1;
> -                     else
> -                             slash = 0;
> -                     continue;
> +                     if ((pfp = fopen(*dbp, "r")) == NULL)
> +                             break;
> +                     eof = 0;
>               }
> -             if (line[len - 2] == '\\')
> -                     slash = 1;
> -             else
> -                     slash = 0;
>  
>               /*
> -              * Line points to a name line.
> +              * Read in a record implementing line continuation.
>                */
> -             done = 0;
> -             np = nbuf;
> +             rp = record;
>               for (;;) {
> -                     for (cp = line; *cp != '\0'; cp++) {
> -                             if (*cp == ',') {
> -                                     *np++ = ',';
> -                                     done = 1;
> -                                     break;
> +                     if (bp >= b_end) {
> +                             size_t n;
> +
> +                             n = fread(buf, 1, sizeof(buf), pfp);
> +                             if (n == 0) {
> +                                     eof = feof(pfp);
> +                                     if (eof)
> +                                             break;
> +                                     else
> +                                             goto done;
>                               }
> -                             *np++ = *cp;
> +                             b_end = buf + n;
> +                             bp = buf;
>                       }
> -                     if (done) {
> -                             *np = '\0';
> -                             break;
> -                     } else { /* name field extends beyond the line */
> -                             line = fgetln(pfp, &len);
> -                             if (line == NULL) {
> -                                     if (ferror(pfp)) {
> -                                             (void)igetclose();
> -                                             return (-1);
> +
> +                     c = *bp++;
> +                     if (c == '\n') {
> +                             if (bp >= b_end) {
> +                                     size_t n;
> +
> +                                     n = fread(buf, 1, sizeof(buf), pfp);
> +                                     if (n == 0) {
> +                                             eof = feof(pfp);
> +                                             if (eof)
> +                                                     break;
> +                                             else
> +                                                     goto done;
>                                       }
> -                                     /* Move on to next file. */
> -                                     (void)fclose(pfp);
> -                                     pfp = NULL;
> -                                     ++dbp;
> -                                     /* NUL terminate nbuf. */
> -                                     *np = '\0';
> +                                     b_end = buf + n;
> +                                     bp = buf;
> +                             }
> +                             if (rp > record && isspace(*bp))
> +                                     continue;
> +                             else
>                                       break;
> -                             } else
> -                                     /* XXX - assumes newline */
> -                                     line[len - 1] = '\0';
> +                     }
> +                     if (rp <= record || *(rp - 1) != ',' || !isspace(c))
> +                             *rp++ = c;
> +
> +                     /*
> +                      * Enforce loop invariant: if no room
> +                      * left in record buffer, try to get
> +                      * some more.
> +                      */
> +                     if (rp >= r_end) {
> +                             size_t newsize, off;
> +                             char *nrecord;
> +
> +                             off = rp - record;
> +                             newsize = r_end - record + BFRAG;
> +                             nrecord = realloc(record, newsize);
> +                             if (nrecord == NULL)
> +                                     goto done;
> +                             record = nrecord;
> +                             r_end = record + newsize;
> +                             rp = record + off;
>                       }
>               }
> -             rp = buf;
> -             for(cp = nbuf; *cp != '\0'; cp++)
> -                     if (*cp == '|' || *cp == ',')
> -                             break;
> -                     else
> -                             *rp++ = *cp;
> +             /* loop invariant lets us do this */
> +             *rp++ = '\0';
>  
> -             *rp = '\0';
> -             status = getent(bp, &dummy, db_array, -1, buf, 0);
> -             if (status == -2 || status == -3)
> -                     (void)igetclose();
> +             /*
> +              * Toss blank lines and comments.
> +              */
> +             if (*record == '\0' || *record == '#')
> +                     continue;
>  
> -             return (status + 1);
> -     }
> -     /* NOTREACHED */
> +             /* rewind to end of record */
> +             fseeko(pfp, (off_t)(bp - b_end), SEEK_CUR);
> +
> +             /* we pass the record to getent() in cap */
> +             *cap = record;
> +             len = rp - record;
> +
> +             /* return value of getent() is one less than igetnext() */
> +             pos = ftello(pfp);
> +             status = getent(cap, &len, dbp, pfp, NULL, 0) + 1;
> +             if (status > 0)
> +                     fseeko(pfp, pos, SEEK_SET);
> +             break;
> +     }
> +done:
> +     serrno = errno;
> +     free(record);
> +     if (status <= 0)
> +             (void)igetclose();
> +     errno = serrno;
> +
> +     return (status);
>  }

Reply via email to