Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Mar 2002 01:20:02 -0800 (PST)
From:      "Tim J. Robbins" <tim@robbins.dropbear.id.au>
To:        freebsd-standards@FreeBSD.org
Subject:   Re: standards/36191: P1003.1-2001 csplit utility
Message-ID:  <200203270920.g2R9K2K53874@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR standards/36191; it has been noted by GNATS.

From: "Tim J. Robbins" <tim@robbins.dropbear.id.au>
To: Stefan Farfeleder <e0026813@stud3.tuwien.ac.at>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: standards/36191: P1003.1-2001 csplit utility
Date: Wed, 27 Mar 2002 20:06:41 +1100

 On Tue, Mar 26, 2002 at 08:07:20PM +0100, Stefan Farfeleder wrote:
 
 > According to P1003.1-2001 '+' is optional.
 
 > Why is a negative offset a 'bad offset'?
 
 Thanks for pointing these out.
 
 > > X	if (sufflen + strlen(prefix) >= PATH_MAX)
 > > X		errx(1, "name too long");
 > 
 > It might be better to check this for each file.
 
 I've decided to do what GNU csplit does, and stop making output files
 once the maximum number is reached. The standard isn't clear about this.
 
 > The improvement posted by Brian F. Feldman (and reposted by you as a
 > patch) has a bug:
 > 
 > >+	snprintf(currfile, sizeof(currfile), "%s%0*ld", prefix, sufflen,
 > >+	    nfiles);
 > 
 > >+		snprintf(fnbuf, sizeof(fnbuf), "%s%0*ld", prefix, sufflen, i);
 > 
 > sufflen has type long, but '*' wants an int.
 
 Fixed.
 
 Here is a new patch incorporating fixes for the problems you found.
 
 
 --- csplit.c	2002/03/23 03:36:26	1.18
 +++ csplit.c	2002/03/27 09:01:24	1.21
 @@ -44,7 +44,7 @@
  
  #include <sys/cdefs.h>
  __FBSDID("$FreeBSD$");
 -__RCSID("$Id: csplit.c,v 1.18 2002/03/23 03:36:26 tim Exp $");
 +__RCSID("$Id: csplit.c,v 1.21 2002/03/27 09:01:24 tim Exp $");
  
  #include <sys/types.h>
  
 @@ -80,6 +80,7 @@
  long lineno;			/* Current line number in input file */
  long reps;			/* Number of repetitions for this pattern */
  long nfiles;			/* Number of files output so far */
 +long maxfiles;			/* Maximum number of files we can create */
  char currfile[PATH_MAX];	/* Current output file */
  const char *infn;		/* Name of the input file */
  FILE *infile;			/* Input file handle */
 @@ -93,7 +94,7 @@
  {
  	FILE *fp;
  
 -	snprintf(currfile, sizeof(currfile), "%s%0*ld", prefix, sufflen,
 +	snprintf(currfile, sizeof(currfile), "%s%0*ld", prefix, (int)sufflen,
  	    nfiles);
  	if ((fp = fopen(currfile, "w+")) == NULL)
  		err(1, "%s", currfile);
 @@ -113,7 +114,8 @@
  		return;
  
  	for (i = 0; i < nfiles; i++) {
 -		snprintf(fnbuf, sizeof(fnbuf), "%s%0*ld", prefix, sufflen, i);
 +		snprintf(fnbuf, sizeof(fnbuf), "%s%0*ld", prefix,
 +		    (int)sufflen, i);
  		unlink(fnbuf);
  	}
  }
 @@ -186,7 +188,7 @@
  			errx(1, "can't read overflowed output");
  		if (fseek(ofp, -(long)nread, SEEK_CUR) != 0)
  			err(1, "%s", currfile);
 -		for (i = 0; i < nread; i++)
 +		for (i = 1; i <= nread; i++)
  			if (buf[nread - i] == '\n' && n-- == 0)
  				break;
  	} while (n > 0);
 @@ -221,11 +223,9 @@
  	*pofs++ = '\0'; /* point to offset from regexp, zap trailing char */
  
  	if (*pofs != '\0') {
 -		if (*pofs != '+' && *pofs != '-')
 -			errx(1, "%s: bad offset", pofs);
  		errno = 0;
  		ofs = strtol(pofs, &ep, 10);
 -		if (ofs < 0 || *ep != '\0' || errno != 0)
 +		if (*ep != '\0' || errno != 0)
  			errx(1, "%s: bad offset", pofs);
  	} else
  		ofs = 0;
 @@ -296,7 +296,7 @@
  	if (lastline <= lineno)
  		errx(1, "%s: can't go backwards", expr);
  
 -	for (;;) {
 +	while (nfiles < maxfiles - 1) {
  		ofp = newfile();
  		while (lineno + 1 != lastline)
  			if ((p = getline()) == NULL || fputs(p, ofp) != 0)
 @@ -318,6 +318,7 @@
  	char *ep, *p;
  	FILE *ofp;
  	int ch;
 +	long i, n;
  
  	kflag = sflag = 0;
  	prefix = "xx";
 @@ -369,7 +370,15 @@
  	truncofs = 0;
  	overfile = NULL;
  
 -	while ((expr = *argv++) != NULL) {
 +	for (maxfiles = 1, i = 0; i < sufflen; i++) {
 +		n = maxfiles;
 +		maxfiles *= 10;
 +		if (maxfiles / 10 != n)
 +			errx(1, "%ld: suffix too long (limit %ld)",
 +			    sufflen, i);
 +	}
 +
 +	while (nfiles < maxfiles - 1 && (expr = *argv++) != NULL) {
  		/* Look ahead & see if this pattern has any repetitions */
  		if (*argv != NULL && **argv == '{') {
  			errno = 0;
 @@ -384,7 +393,7 @@
  			/* Regular expression copy or ignore */
  			do
  				do_rexp(expr);
 -			while (reps-- != 0);
 +			while (reps-- != 0 && nfiles < maxfiles - 1);
  		} else if (isdigit(*expr))
  			do_lineno(expr);
  		else

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-standards" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200203270920.g2R9K2K53874>