NetBSD-Bugs archive

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

Re: standards/11228



The following reply was made to PR standards/11228; it has been noted by GNATS.

From: Roy Marples <roy%NetBSD.org@localhost>
To: 
Cc: gnats-bugs%gnats.netbsd.org@localhost
Subject: Re: standards/11228
Date: Thu, 11 Dec 2008 12:39:58 +0000

 --=-HVYMB68FLwp8tn7UjP/x
 Content-Type: text/plain
 Content-Transfer-Encoding: quoted-printable
 
 This patch should add the requested functionality.
 It also has the advantage of not using a fixed size buffer.
 
 Comments?
 
 Thanks
 
 Roy
 
 Index: unexpand/unexpand.c
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /cvsroot/src/usr.bin/unexpand/unexpand.c,v
 retrieving revision 1.13
 diff -u -p -r1.13 unexpand.c
 --- unexpand/unexpand.c        21 Jul 2008 14:19:27 -0000      1.13
 +++ unexpand/unexpand.c        11 Dec 2008 11:56:42 -0000
 @@ -45,6 +45,7 @@ __RCSID("$NetBSD: unexpand.c,v 1.13 2008
  /*
   * unexpand - put tabs into a file replacing blanks
   */
 +#include <limits.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
 @@ -52,45 +53,58 @@ __RCSID("$NetBSD: unexpand.c,v 1.13 2008
  #include <errno.h>
  #include <err.h>
 =20
 -char  genbuf[BUFSIZ];
 -char  linebuf[BUFSIZ];
 +#define NSTOPS 20
 =20
 -int   main(int, char **);
 -void  tabify(int, uint);
 +static int    all;
 +static size_t nstops;
 +static size_t         tabstops[NSTOPS];
 +
 +int           main(int, char **);
 +static void   tabify(const char *, size_t);
 =20
  int
  main(int argc, char **argv)
  {
 -      int all, c;
 -      uint tabsize;
 -      ulong l;
 -      char *ep;
 +      int c;
 +      char *ep, *tab;
 +      char *line;
 +      size_t i, len;
 =20
        setprogname(argv[0]);
 =20
 -      all =3D 0;
 -      tabsize =3D 8;
 +      nstops =3D 1;
 +      tabstops[0] =3D 8;
 +
        while ((c =3D getopt(argc, argv, "at:")) !=3D -1) {
                switch (c) {
                case 'a':
                        all++;
                        break;
                case 't':
 -                      errno =3D 0;
 -                      l =3D strtoul(optarg, &ep, 0);
 -                      /*
 -                       * If every input char is a tab, the line length
 -                       * must not exceed maxuint.
 -                       */
 -                      tabsize =3D (int)l * BUFSIZ;
 -                      tabsize /=3D BUFSIZ;
 -                      if (*ep !=3D 0 || errno !=3D 0 || (ulong)tabsize !=3D l)
 -                              errx(EXIT_FAILURE, "Invalid tabstop \"%s\"",
 -                                  optarg);
 +                      all =3D 0;
 +                      nstops =3D 0;
 +                      while ((tab =3D strsep(&optarg, ", "))) {
 +                              if (*tab =3D=3D '\0')=20
 +                                      continue;=20
 +                              if (nstops >=3D NSTOPS)=20
 +                                      errx(EXIT_FAILURE,=20
 +                                           "too many tab stops (max %d)",
 +                                           NSTOPS);=20
 +                              errno =3D 0;
 +                              i =3D strtoul(tab, &ep, 0);
 +                              if (errno || *ep || i <=3D 0)
 +                                      errx(EXIT_FAILURE,
 +                                           "%s: invalid tabstop", tab);
 +                              if (nstops > 0 && tabstops[nstops - 1] >=3D i)
 +                                      errx(EXIT_FAILURE,
 +                                           "%s: bad tabstop spec", tab);
 +                              tabstops[nstops++] =3D i;
 +                      }
                        break;
                case '?':
                default:
 -                      fprintf(stderr, "usage: %s [-a] [-t tabstop] [file 
...]\n",
 +                      fprintf(stderr, "usage: %s"
 +                              " [-a] [-t tabstop] [file ...]\n",
                                getprogname());
                        exit(EXIT_FAILURE);
                        /* NOTREACHED */
 @@ -107,58 +121,84 @@ main(int argc, char **argv)
                        }
                        argc--, argv++;
                }
 -              while (fgets(genbuf, BUFSIZ, stdin) !=3D NULL) {
 -                      tabify(all, tabsize);
 -                      printf("%s", linebuf);
 -              }
 +              while ((line =3D fgetln(stdin, &len)) !=3D NULL)
 +                      tabify(line, len);
        } while (argc > 0);
        exit(EXIT_SUCCESS);
        /* NOTREACHED */
  }
 =20
 -void
 -tabify(int all, uint tabsize)
 +static void
 +tabify(const char *line, size_t len)
  {
 -      char *cp, *dp;
 -      uint dcol;
 -      uint ocol;
 -      uint tcol;
 -
 -      ocol =3D 0;
 -      dcol =3D 0;
 -      cp =3D genbuf, dp =3D linebuf;
 -      for (;;) {
 -              switch (*cp) {
 +      const char *e, *p;
 +      size_t dcol, ocol, limit, n;
 =20
 -              case ' ':
 +      dcol =3D ocol =3D 0;
 +      limit =3D nstops =3D=3D 1 ? UINT_MAX : tabstops[nstops - 1] - 1;
 +      e =3D line + len;
 +      for (p =3D line; p < e; p++) {
 +              if (*p =3D=3D ' ') {
                        dcol++;
 -                      break;
 -
 -              case '\t':
 -                      dcol =3D (dcol + tabsize) / tabsize * tabsize;
 -                      break;
 -
 -              default:
 -                      if (dcol > ocol + 1) {
 -                              tcol =3D (ocol + tabsize) / tabsize * tabsize;
 -                              while (tcol <=3D dcol) {
 -                                      *dp++ =3D '\t';
 -                                      ocol =3D tcol;
 -                                      tcol +=3D tabsize;
 +                      continue;
 +              } else if (*p =3D=3D '\t') {
 +                      if (nstops =3D=3D 1) {
 +                              dcol =3D (1 + dcol / tabstops[0]) * tabstops[0];
 +                              continue;
 +                      } else {
 +                              for (n =3D 0;
 +                                   tabstops[n] - 1 < dcol && n < nstops;
 +                                   n++)
 +                                      ;
 +                              if (n < nstops - 1 && tabstops[n] - 1 < limit) {
 +                                      dcol =3D tabstops[n];
 +                                      continue;
                                }
                        }
 -                      while (ocol < dcol) {
 -                              *dp++ =3D ' ';
 -                              ocol++;
 -                      }
 -                      if (*cp =3D=3D 0 || all =3D=3D 0) {
 -                              strlcpy(dp, cp,
 -                                  sizeof(linebuf) - (dp - linebuf));
 -                              return;
 +              }
 +
 +              /* Output our tabs */
 +              if (nstops =3D=3D 1) {
 +                      while (((ocol + tabstops[0]) / tabstops[0]) <=3D
 +                             (dcol / tabstops[0]))
 +                      {
 +                              if (dcol - ocol < 2)
 +                                      break;
 +                              putchar('\t');
 +                              ocol =3D (1 + ocol / tabstops[0]) * tabstops[0];
 +                      }
 +              } else {
 +                      for (n =3D 0; tabstops[n] - 1 < ocol && n < nstops; n++)
 +                              ;
 +                      while (ocol < dcol && n < nstops && ocol < limit) {
 +                              putchar('\t');
 +                              ocol =3D tabstops[n++];
 +                      }
 +              }
 +
 +              /* Output remaining spaces */
 +              while (ocol < dcol && ocol < limit) {
 +                      putchar(' ');
 +                      ocol++;
 +              }
 +
 +              /* Output our char */
 +              putchar(*p);
 +              if (*p =3D=3D '\b') {
 +                      if (ocol > 0) {
 +                              ocol--;
 +                              dcol--;
                        }
 -                      *dp++ =3D *cp;
 -                      dcol =3D ++ocol;
 +              } else {
 +                      ocol++;
 +                      dcol++;
 +              }
 +
 +              /* Output remainder of line */
 +              if (!all || dcol >=3D limit) {
 +                      for (p++; p < e; p++)
 +                              putchar(*p);
 +                      return;
                }
 -              cp++;
        }
  }
 Index: expand/expand.1
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /cvsroot/src/usr.bin/expand/expand.1,v
 retrieving revision 1.10
 diff -u -p -r1.10 expand.1
 --- expand/expand.1    7 Aug 2003 11:13:39 -0000       1.10
 +++ expand/expand.1    11 Dec 2008 11:56:42 -0000
 @@ -29,7 +29,7 @@
  .\"
  .\"   @(#)expand.1    8.1 (Berkeley) 6/9/93
  .\"
 -.Dd April 8, 2003
 +.Dd December 11, 2003
  .Dt EXPAND 1
  .Os
  .Sh NAME
 @@ -43,7 +43,7 @@
  .Op Ar
  .Nm unexpand
  .Op Fl a
 -.Op Fl t Ar tabstop
 +.Op Fl t Ar tab1,tab2,...,tabn=20
  .Op Ar
  .Sh DESCRIPTION
  .Nm
 
 
 --=-HVYMB68FLwp8tn7UjP/x
 Content-Type: application/pgp-signature; name=signature.asc
 Content-Description: This is a digitally signed message part
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.9 (NetBSD)
 
 iQEcBAABAgAGBQJJQQoeAAoJEFl/l+qa1FVJ1MkH/1sOIY7GBynBBqCX7sfS8vHk
 zb0CNp41DswCTNTBOF71buVKIIJh8RTczftfIb0UntkNCDXIAHbdjBoMJUevZjoq
 uCUjnRzvGruOLcvEOeGhyTqQEgoyXiTW1iim5f5We5lQoHhZrAt7aaRGTpxcmeGj
 3Y9bGvPS2f4TNX5gJMZx5rcsjBj7qkDWZBjgbFEpaOmegPVOB9ZxwGL0slTj0JdT
 Reah57P4Z20uQMpi6QVY7wv85SB4FS9At7h9mCRcBsf3G1KRoPNT44cW3h9FXo4/
 3gy8KXng35Hc8uzr9nUZmCKrS35TzKvZxfwsME6L0zcEwB1pGfe9dRJceSHVR8I=
 =jNAR
 -----END PGP SIGNATURE-----
 
 --=-HVYMB68FLwp8tn7UjP/x--
 


Home | Main Index | Thread Index | Old Index