<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf8">
<title>/usr/web/sources/contrib/uriel/cut.c - Plan 9 from Bell Labs</title>
<!-- THIS FILE IS AUTOMATICALLY GENERATED. -->
<!-- EDIT sources.tr INSTEAD. -->
</meta>
</head>
<body>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><a href="/plan9/">Plan 9 from Bell Labs</a>&rsquo;s /usr/web/sources/contrib/uriel/cut.c</span></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
Copyright © 2009 Alcatel-Lucent.<br />
Distributed under the
<a href="/plan9/license.html">Lucent Public License version 1.02</a>.
<br />
<a href="/plan9/download.html">Download the Plan 9 distribution.</a>
</font>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<table width="100%" cellspacing=0 border=0><tr><td align="center">
<table cellspacing=0 cellpadding=5 bgcolor="#eeeeff"><tr><td align="left">
<pre>
<!-- END HEADER -->
/*      $OpenBSD: cut.c,v 1.11 2003/06/10 22:20:45 deraadt Exp $        */
/*      $NetBSD: cut.c,v 1.9 1995/09/02 05:59:23 jtc Exp $      */

/*
* Copyright (c) 1989, 1993
*      The Regents of the University of California.  All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam S. Moskowitz of Menlo Consulting and Marciano Pitargue.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
*    may be used to endorse or promote products derived from this software
*    without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1989, 1993\n\
       The Regents of the University of California.  All rights reserved.\n";
#endif /* not lint */

#ifndef lint
#if 0
static char sccsid[] = "@(#)cut.c       8.3 (Berkeley) 5/4/95";
#endif
static char rcsid[] = "$OpenBSD: cut.c,v 1.11 2003/06/10 22:20:45 deraadt Exp $";
#endif /* not lint */

#include &lt;ctype.h&gt;
#include &lt;err.h&gt;
#include &lt;errno.h&gt;
#include &lt;limits.h&gt;
#include &lt;locale.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;unistd.h&gt;

int     cflag;
char    dchar;
int     dflag;
int     fflag;
int     sflag;

void    c_cut(FILE *, char *);
void    f_cut(FILE *, char *);
void    get_list(char *);
void    usage(void);

int
main(int argc, char *argv[])
{
       FILE *fp;
       void (*fcn)(FILE *, char *);
       int ch;

       setlocale (LC_ALL, "");

       dchar = '\t';                   /* default delimiter is \t */

       /* Since we don't support multi-byte characters, the -c and -b
          options are equivalent, and the -n option is meaningless. */
//      while ((ch = getopt(argc, argv, "b:c:d:f:sn")) != -1)
       while (--argc &gt; 0 &amp;&amp; (++argv)[0][0] == '-')
               switch(argv[0][1]) {
               case 'b':
               case 'c':
                       fcn = c_cut;
                       get_list(&amp;(argv[0][2]));
                       cflag = 1;
                       break;
               case 'd':
                       dchar = argv[0][2];
                       dflag = 1;
                       break;
               case 'f':
                       get_list(&amp;(argv[0][2]));
                       fcn = f_cut;
                       fflag = 1;
                       break;
               case 's':
                       sflag = 1;
                       break;
               case 'n':
                       break;
               case '?':
               default:
                       usage();
               }


       if (fflag) {
               if (cflag)
                       usage();
       } else if (!cflag || dflag || sflag)
               usage();

       if (*argv)
               for (; *argv; ++argv) {
                       if (!(fp = fopen(*argv, "r")))
                               err(1, "%s", *argv);
                       fcn(fp, *argv);
                       (void)fclose(fp);
               }
       else
               fcn(stdin, "stdin");
       exit(0);
}

int autostart, autostop, maxval;

#define _POSIX2_LINE_MAX 512
char positions[_POSIX2_LINE_MAX + 1];

void
get_list(char *list)
{
       int setautostart, start, stop;
       char *pos;
       char *p;

       /*
        * set a byte in the positions array to indicate if a field or
        * column is to be selected; use +1, it's 1-based, not 0-based.
        * This parser is less restrictive than the Draft 9 POSIX spec.
        * POSIX doesn't allow lists that aren't in increasing order or
        * overlapping lists.  We also handle "-3-5" although there's no
        * real reason too.
        */
       while ((p = strsep(&amp;list, ", \t"))) {
               setautostart = start = stop = 0;
               if (*p == '-') {
                       ++p;
                       setautostart = 1;
               }
               if (isdigit(*p)) {
                       start = stop = strtol(p, &amp;p, 10);
                       if (setautostart &amp;&amp; start &gt; autostart)
                               autostart = start;
               }
               if (*p == '-') {
                       if (isdigit(p[1]))
                               stop = strtol(p + 1, &amp;p, 10);
                       if (*p == '-') {
                               ++p;
                               if (!autostop || autostop &gt; stop)
                                       autostop = stop;
                       }
               }
               if (*p)
                       errx(1, "[-cf] list: illegal list value");
               if (!stop || !start)
                       errx(1, "[-cf] list: values may not include zero");
               if (stop &gt; _POSIX2_LINE_MAX)
                       errx(1, "[-cf] list: %d too large (max %d)",
                           stop, _POSIX2_LINE_MAX);
               if (maxval &lt; stop)
                       maxval = stop;
               for (pos = positions + start; start++ &lt;= stop; *pos++ = 1)
                       ;
       }

       /* overlapping ranges */
       if (autostop &amp;&amp; maxval &gt; autostop)
               maxval = autostop;

       /* set autostart */
       if (autostart)
               memset(positions + 1, '1', autostart);
}

/* ARGSUSED */
void
c_cut(FILE *fp, char *fname)
{
       int ch, col;
       char *pos;

       for (;;) {
               pos = positions + 1;
               for (col = maxval; col; --col) {
                       if ((ch = getc(fp)) == EOF)
                               return;
                       if (ch == '\n')
                               break;
                       if (*pos++)
                               (void)putchar(ch);
               }
               if (ch != '\n') {
                       if (autostop)
                               while ((ch = getc(fp)) != EOF &amp;&amp; ch != '\n')
                                       (void)putchar(ch);
                       else
                               while ((ch = getc(fp)) != EOF &amp;&amp; ch != '\n')
                                       ;
               }
               (void)putchar('\n');
       }
}

void
f_cut(FILE *fp, char *fname)
{
       int ch, field, isdelim;
       char *pos, *p, sep;
       int output;
       size_t len;
       char *lbuf, *tbuf;

       for (sep = dchar, tbuf = NULL; (lbuf = fgetln(fp, &amp;len));) {
               output = 0;
               if (lbuf[len - 1] != '\n') {
                       /* no newline at the end of the last line so add one */
                       if ((tbuf = (char *)malloc(len + 1)) == NULL)
                               err(1, NULL);
                       memcpy(tbuf, lbuf, len);
                       tbuf[len] = '\n';
                       lbuf = tbuf;
               }
               for (isdelim = 0, p = lbuf;; ++p) {
                       ch = *p;
                       /* this should work if newline is delimiter */
                       if (ch == sep)
                               isdelim = 1;
                       if (ch == '\n') {
                               if (!isdelim &amp;&amp; !sflag)
                                       (void)fwrite(lbuf, len, 1, stdout);
                               break;
                       }
               }
               if (!isdelim)
                       continue;

               pos = positions + 1;
               for (field = maxval, p = lbuf; field; --field, ++pos) {
                       if (*pos) {
                               if (output++)
                                       (void)putchar(sep);
                               while ((ch = *p++) != '\n' &amp;&amp; ch != sep)
                                       (void)putchar(ch);
                       } else
                               while ((ch = *p++) != '\n' &amp;&amp; ch != sep)
                                       ;
                       if (ch == '\n')
                               break;
               }
               if (ch != '\n') {
                       if (autostop) {
                               if (output)
                                       (void)putchar(sep);
                               for (; (ch = *p) != '\n'; ++p)
                                       (void)putchar(ch);
                       } else
                               for (; (ch = *p) != '\n'; ++p)
                                       ;
               }
               (void)putchar('\n');
       }
       if (tbuf)
               free(tbuf);
}

void
usage(void)
{
       (void)fprintf(stderr,
               "usage:\tcut -c list [file1 ...]\n"
               "\tcut -f list [-s] [-d delim] [file ...]\n"
               "\tcut -b list [-n] [file ...]\n");
       exit(1);
}
<!-- BEGIN TAIL -->
</pre>
</td></tr></table>
</td></tr></table>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"></span></p>
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="margin-top: 0; margin-bottom: 0.33in"></p>
<center><table border="0"><tr>
<td valign="middle"><a href="http://www.alcatel-lucent.com/"><img border="0" src="/plan9/img/logo_ft.gif" alt="Bell Labs" />
</a></td>
<td valign="middle"><a href="http://www.opensource.org"><img border="0" alt="OSI certified" src="/plan9/img/osi-certified-60x50.gif" />
</a></td>
<td><img style="padding-right: 45px;" alt="Powered by Plan 9" src="/plan9/img/power36.gif" />
</td>
</tr></table></center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center>
<span style="font-size: 10pt">(<a href="/plan9/">Return to Plan 9 Home Page</a>)</span>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
<span style="font-size: 10pt"><a href="http://www.lucent.com/copyright.html">Copyright</a></span>
<span style="font-size: 10pt">© 2009 Alcatel-Lucent.</span>
<span style="font-size: 10pt">All Rights Reserved.</span>
<br />
<span style="font-size: 10pt">Comments to</span>
<span style="font-size: 10pt"><a href="mailto:[email protected]">[email protected]</a>.</span>
</font></center>
</body>
</html>