🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: net.sources.bugs
1 messages
1 total messages Started by benjamin Sat, 28 Mar 1987 21:42
bug in cut
#987
Author: benjamin
Date: Sat, 28 Mar 1987 21:42
293 lines
7187 bytes
>It is very strange that the original cut posted by John Weald works
>on the (,) specifics but not on the (-) specifics.  And your mod. of
>cut DOES work on the (-) specifics but NOT (,) specifics.
>The orginal one is from mod.sources Feb 24, 87 and your mod. is from
>net.sources March 12, 87.
>
>Dennis Chen @ Olivetti ATC
>{allegra, fortune, glacier, hplabs, idi, ihnp4, sun}!oliveb!dchen
>

Guess I made a slight booboo in the list() procedure.
Here's the new posting with the fixup.  

Thanks Dennis !


benjamin@uhmanoa.ICS.HAWAII.EDU

----------------------------- cut cut ------------------------------------
#! /bin/sh
#
# This is John Weald's 'cut' program which did not seem to
# work correctly. So I've made some modifications, seems okay
# right now, these are legal: 
#  
#	cut -f3 -d' '  and   cut -f1,3,2,4-6  
#
#   
#		   SHAR AND ENJOY !!!!!
#
PATH=/bin:/usr/bin:/usr/ucb; export PATH
echo shar: 'extracting "'cut.c'" '
if test -f 'cut.c' ; then 
  echo shar: will not over-write existing file "'cut.c'"
else
sed 's/^X//' >cut.c <<'@//E*O*F cut.c//'
X/*
X *  This acts the same as SV cut(1), except that the list of numbers
X *  does not have to be assending.
X *
X *  John Weald
X */
X#include <stdio.h>
X#include <ctype.h>
X
X#define MAXLINE	1024		/* The max. length of a line		*/
X#define DEBUG	0
X
Xextern void exit();
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	extern char *optarg;
X	extern int optind;
X
X	static int fields[MAXLINE];/* The field markers. True if this field */
X				   /* is to be cut, False otherwise	*/
X	FILE *fp;		   /* All the input files or stdin	*/
X	char buf[MAXLINE];	   /* The input buffer			*/
X	int c;			   /* The command line option		*/
X	int err = 0;		   /* True if error in command line	*/
X	int fflag = 0;		   /* True if -f on command line	*/
X	int cflag = 0;		   /* True if -c on command line	*/
X	int suppress = 0;	   /* Suppress lines with no delimitor	*/
X	char fs = '\t';		   /* The field separator		*/
X
X
X	while ((c = getopt(argc, argv, "f:d:c:s")) != EOF)
X	{
X		switch (c)
X		{
X		   case 'f':
X			/* By Field */
X			list(fields, optarg);
X			fflag++;
X			if (cflag)
X				err++;
X			break;
X
X		   case 'c':
X			/* By character */
X			list(fields, optarg);
X			/* Implied suppress */
X			suppress++;
X			cflag++;
X			if (fflag)
X				err++;
X			break;
X
X		   case 'd':
X			/* A new field spererator */
X			fs = *optarg;
X			break;
X
X		   case 's':
X			suppress++;
X			break;
X
X		   default:
X			prusage();
X		}
X	}
X
X	if (!cflag && !fflag)
X	{
X		fprintf(stderr, "Must have one of -f or -c\n");
X		err++;
X	}
X	if (err)
X		prusage();
X
X
X	/*
X	 * Loop on all the files.
X	 */
X	do {
X		if (optind == argc)
X			fp = stdin;
X		else if ((fp = fopen(argv[optind], "r")) == (FILE *)NULL)
X		{
X			fprintf(stderr, "Failed to open file %s\n", 
X					argv[optind]);
X			exit(1);
X		}
X
X		/*
X		 * Loop on all lines in the file.
X		 */
X		while (fgets(buf, sizeof(buf), fp) != (char *)NULL)
X		{
X			cut(buf, fields, fs, suppress, cflag);
X		}
X		(void)fclose(fp);
X	} while (++optind < argc);
X
X	exit(0);
X/* NOTREACHED */
X}
X
X/*
X * Cut the line. This handles both character and field cutting.
X * For character cutting the f array gives character positions, for
X * fields it gives the field number. It must be indexed by either the
X * character number or the field number.
X */
Xcut(in, f, fs, sup, c_or_f)
Xregister char *in;		/* The input line			*/
Xint f[];			/* The field cutting flags		*/
Xchar fs;			/* The field seperator			*/
Xint sup;			/* Suppress lines with no-delimitor?	*/
Xint c_or_f;			/* Cut by char. (true), or field (false)*/
X{
X	char obuf[MAXLINE];	/* Output buffer			*/
X	register char *optr = obuf;
X	register int i;		/* Character count			*/
X	register int fld;	/* The field count			*/
X	char *instart = in;	/* To print lines with no delimiters	*/
X
X 	if (DEBUG)	printf("c_or_f=%d\n",c_or_f);	
X	for (fld = 0, i = 0; i < MAXLINE; i++)
X	{
X		if (*in == '\n')
X		{
X			/* End of the line */
X
X			*optr = '\0';
X			/* Any thing to cut? */
X			if (optr != obuf)
X			{
X				/* Get ride of trailing seperator */
X				if (*(optr - 1) == fs)
X					*(optr - 1) = '\0';
X				puts(obuf);
X			}
X			else if (!sup)
X				printf(instart);
X			return;
X		}
X		if (DEBUG)   printf("%d",f[c_or_f ? i : fld]);
X		if (f[c_or_f ? i : fld])
X		{
X			*optr++ = *in;
X		}
X
X		/* End of field? */
X		if (*in++ == fs)
X			fld++;
X	}
X
X	fprintf(stderr, "Line too long, maximum length is %d\n", MAXLINE);
X	exit(1);
X}
X
X/*
X * Parse the list argument. The format is:
X *	n,n
X * where n is either a number or a range of numbers in the format
X *	m-l
X * m or l  may be absent, indicating the start or end of the lines respectivly.
X * Numbers must be in increasing order for m-l format, but not for n,n.
X * Field numbers start at 1, but index into fields array starts at 0.
X * 
X */
Xlist(f, l)
Xint f[];		/* The fields				*/
Xchar *l;		/* The list				*/
X{
X	int range = 0;	/* True if m-l format			 */
X	int low, high;	/* the low and high numbers in a m-l pair*/
X	int i;
X
X	low = high = 0; 
X
X	while (1)
X	{
X		switch(*l)
X		{
X		   case '\0':
X			if (low > 0 ) f[low-1]++;
X			return;
X
X		   case ',':
X			l++;
X		       	if (!range) f[low-1]++;
X			else {
X				if (isdigit( (int)*l ))
X				{
X					f[ (low=atoi(l))-1 ]++;
X					while(isdigit( (int)*l ) ) l++;
X				}
X			}
X			range = 0;
X			low = 1;
X			break;
X
X		   case '-':
X			l++;
X			range++;
X			/* Is it m-<nothing> */
X			if (isdigit((int)*l))
X			{
X				high = atoi(l);
X				/* Skip the digits */
X				while (isdigit((int) *l))
X					l++;
X			}
X			else
X				high = MAXLINE;
X
X			/* Is the range the correct way around? */
X			if (low > high)
X			{
X				fprintf(stderr, "Bad c/f list: %d > %d\n", 
X							low, high);
X				exit(1);
X			}
X			/* Set the field flags for the range */
X			for(i = low - 1; i < high; i++)
X				f[i]++;
X			break;
X
X		    default:
X			/* either a number or an error */
X			if (!isdigit((int) *l))
X			{
X				fprintf(stderr, "Bad c/f list at %s\n", l);
X				exit(1);
X			}
X			low = atoi(l);
X			if (low == 0)
X			{
X				fprintf(stderr, "Fields start at 1 not 0\n");
X				exit(1);
X			}
X			/* Skip the digits */
X			while (isdigit((int) *l))
X				l++;
X			break;
X		}
X	}
X}
X
Xprusage()
X{
X	fprintf(stderr, "cut [-d<delimitor>] [-s] -c<list>|-f<list> [files]\n");
X	exit(1);
X}
@//E*O*F cut.c//
echo "end of shar"
fi
exit 0
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads