File:  [MW Coherent from dump] / coherent / d / bin / split.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * split.c
 * Usage: split [ -n ] [ infile [ outfile ]]
 *
 * split copies its input file into n-line pieces
 * with output filenames ending in "aa", "ab", ... "zz".
 * "n" (default 1000) is the number of lines per output file,
 * "infile" (default or "-" is standard input) is the file to read,
 * "outfile" (default "x") is the initial part of the output file name.
 * A "-n" option beginning with 'c' (e.g. "-c100000") splits
 * a binary file into characters instead of an ASCII file into lines.
 */

#include <stdio.h>

/*
 * Globals.
 */
int	binary = 0;		/* 0 for ASCII lines, 1 for binary characters */
long	chunk = 1000L;		/* number of lines or chars per output file */
FILE	*ifp = stdin;		/* input file pointer */
char	*outname = "xaa";	/* first output filename */

/*
 * Functions.
 */
long	atol();
void	copy();
void	fatal();
char	*malloc();
void	nextname();
void	options();
char	*strcat();
char	*strcpy();

main(argc, argv) int argc; char *argv[];
{
	register int c;
	register FILE *ofp;
	register char *mode;
	register char *tail;

	options(argc, argv);
	tail = outname + strlen(outname) - 1;
	mode = (binary) ? "wb" : "w";
	while (!feof(ifp) && (c = getc(ifp)) != EOF) {
		ungetc(c, ifp);
		if ((ofp = fopen(outname, mode)) == NULL)
			fatal("split: cannot open output file \"%s\"\n",
				outname);
		copy(ofp);
		if (fclose(ofp) == EOF)
			fatal("split: cannot close output file \"%s\"\n",
				outname);
		nextname(tail);
	}
	exit(0);
}

/*
 * Copy "chunk" lines or characters from "ifp" to "ofp".
 */
void copy(ofp) register FILE *ofp;
{
	register int c;
	register long num;

	for (num = chunk; (c = getc(ifp)) != EOF; ) {
		putc(c, ofp);
		if ((binary || c == '\n') && --num <= 0)
			return;
	}
}

/*
 * Cry and die.
 * Avoids the nonportable "%r" format by assuming char * "cp" follows "fmt".
 * The second argument is omitted if the "fmt" does not require it.
 */
void fatal(fmt, cp) register char *fmt, *cp;
{
	fprintf(stderr, fmt, cp);
	exit(1);
}

/*
 * Set "outname" to the next output file name.
 * If there are no more output files, issue an error message and exit.
 */
void nextname(cp) register char *cp;
{
	if (++*cp <= 'z')
		return;
	*cp = 'a';
	if (++*--cp <= 'z')
		return;
	fatal("split: too many output files\n");
}

/*
 * Process command line options and initialize globals.
 */
void options(argc, argv) register int argc; register char *argv[];
{
	register char *cp;

	if (--argc > 0 && **++argv == '-') {
		cp = ++*argv;
		if (*cp == 'c') {
			binary = 1;
			++cp;
		}
		chunk = atol(cp);
		++argv;
		--argc;
	}
	if (chunk <= 0L || argc > 2)
		fatal("Usage: split [ -n ] [ infile [ outfile ]]\n");
	if (argc > 0) {
		cp = *argv++;
		if (strcmp(cp, "-") != 0
		 && (ifp = fopen(cp, (binary) ? "rb" : "r")) == NULL)
			fatal("split: cannot open input file \"%s\"\n", cp);
	}
	if (argc > 1) {
		cp = *argv++;
		if ((outname = malloc(strlen(cp) + 3)) == NULL)
			fatal("split: \"%s\" too long\n", cp);
		strcpy(outname, cp);
		strcat(outname, "aa");
	}
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.