Пример #1
0
/*
 * vertcol:	print files with more than one column of output down a page
 */
int
vertcol(int argc, char *argv[])
{
	char *ptbf;
	char **lstdat;
	int i;
	int j;
	int cnt = -1;
	int pln;
	int *indy;
	int cvc;
	int *lindy;
	int lncnt;
	int stp;
	int pagecnt;
	int col = colwd + 1;
	int mxlen = pgwd + offst + 1;
	int mclcnt = clcnt - 1;
	struct vcol *vc;
	int mvc;
	int tvc;
	int cw = nmwd + 1;
	int fullcol;
	char *buf;
	char *hbuf;
	char *ohbuf;
	const char *fname;
	FILE *inf;
	int ips = 0;
	int cps = 0;
	int ops = 0;
	int mor = 0;

	/*
	 * allocate page buffer
	 */
	if ((buf = malloc((unsigned)lines*mxlen*sizeof(char))) == NULL) {
		mfail();
		return(1);
	}

	/*
	 * allocate page header
	 */
	if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
		mfail();
		return(1);
	}
	ohbuf = hbuf + offst;
	if (offst)
		(void)memset(hbuf, (int)' ', offst);

	/*
	 * col pointers when no headers
	 */
	mvc = lines * clcnt;
	if ((vc =
	    (struct vcol *)malloc((unsigned)mvc*sizeof(struct vcol))) == NULL) {
		mfail();
		return(1);
	}

	/*
	 * pointer into page where last data per line is located
	 */
	if ((lstdat = (char **)malloc((unsigned)lines*sizeof(char *))) == NULL){
		mfail();
		return(1);
	}

	/*
	 * fast index lookups to locate start of lines
	 */
	if ((indy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {
		mfail();
		return(1);
	}
	if ((lindy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {
		mfail();
		return(1);
	}

	if (nmwd)
		fullcol = col + cw;
	else
		fullcol = col;

	/*
	 * initialize buffer lookup indexes and offset area
	 */
	for (j = 0; j < lines; ++j) {
		lindy[j] = j * mxlen;
		indy[j] = lindy[j] + offst;
		if (offst) {
			ptbf = buf + lindy[j];
			(void)memset(ptbf, (int)' ', offst);
			ptbf += offst;
		} else
			ptbf = buf + indy[j];
		lstdat[j] = ptbf;
	}

	/*
	 * loop by file
	 */
	while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
		if (pgnm) {
			/*
			 * skip to requested page
			 */
			if (inskip(inf, pgnm, lines))
				continue;
			pagecnt = pgnm;
		} else
			pagecnt = 1;
		lncnt = 0;

		/*
		 * loop by page
		 */
		for(;;) {
			ttypause(pagecnt);

			/*
			 * loop by column
			 */
			cvc = 0;
			for (i = 0; i < clcnt; ++i) {
				j = 0;
				/*
				 * if last column, do not pad
				 */
				if (i == mclcnt)
					stp = 1;
				else
					stp = 0;
				/*
				 * loop by line
				 */
				for(;;) {
					/*
					 * is this first column
					 */
					if (!i) {
						ptbf = buf + indy[j];
						lstdat[j] = ptbf;
					} else
						ptbf = lstdat[j];
					vc[cvc].pt = ptbf;

					/*
					 * add number
					 */
					if (nmwd) {
						addnum(ptbf, nmwd, ++lncnt);
						ptbf += nmwd;
						*ptbf++ = nmchar;
					}

					/*
					 * input next line
					 */
					cnt = inln(inf,ptbf,colwd,&cps,1,&mor);
					vc[cvc++].cnt = cnt;
					if (cnt < 0)
						break;
					ptbf += cnt;

					/*
					 * pad all but last column on page
					 */
					if (!stp) {
						/*
						 * pad to end of column
						 */
						if (sflag)
							*ptbf++ = schar;
						else if ((pln = col-cnt) > 0) {
							(void)memset(ptbf,
								(int)' ',pln);
							ptbf += pln;
						}
					}
					/*
					 * remember last char in line
					 */
					lstdat[j] = ptbf;
					if (++j >= lines)
						break;
				}
				if (cnt < 0)
					break;
			}

			/*
			 * when -t (no header) is specified the spec requires
			 * the min number of lines. The last page may not have
			 * balanced length columns. To fix this we must reorder
			 * the columns. This is a very slow technique so it is
			 * only used under limited conditions. Without -t, the
			 * balancing of text columns is unspecified. To NOT
			 * balance the last page, add the global variable
			 * nohead to the if statement below e.g.
			 *
			 * if ((cnt < 0) && nohead && cvc ......
			 */
			--cvc;

			/*
			 * check to see if last page needs to be reordered
			 */
			if ((cnt < 0) && cvc && ((mvc-cvc) >= clcnt)){
				pln = cvc/clcnt;
				if (cvc % clcnt)
					++pln;

				/*
				 * print header
				 */
				if (!nohead && prhead(hbuf, fname, pagecnt))
					return(1);
				for (i = 0; i < pln; ++i) {
					ips = 0;
					ops = 0;
					if (offst&& otln(buf,offst,&ips,&ops,1))
						return(1);
					tvc = i;

					for (j = 0; j < clcnt; ++j) {
						/*
						 * determine column length
						 */
						if (j == mclcnt) {
							/*
							 * last column
							 */
							cnt = vc[tvc].cnt;
							if (nmwd)
								cnt += cw;
						} else if (sflag) {
							/*
							 * single ch between
							 */
							cnt = vc[tvc].cnt + 1;
							if (nmwd)
								cnt += cw;
						} else
							cnt = fullcol;
						if (otln(vc[tvc].pt, cnt, &ips,
								&ops, 1))
							return(1);
						tvc += pln;
						if (tvc >= cvc)
							break;
					}
					/*
					 * terminate line
					 */
					if (otln(buf, 0, &ips, &ops, 0))
						return(1);
				}
				/*
				 * pad to end of page
				 */
				if (prtail((lines - pln), 0))
					return(1);
				/*
				 * done with output, go to next file
				 */
				break;
			}

			/*
			 * determine how many lines to output
			 */
			if (i > 0)
				pln = lines;
			else
				pln = j;

			/*
			 * print header
			 */
			if (pln && !nohead && prhead(hbuf, fname, pagecnt))
				return(1);

			/*
			 * output each line
			 */
			for (i = 0; i < pln; ++i) {
				ptbf = buf + lindy[i];
				if ((j = lstdat[i] - ptbf) <= offst)
					break;
				if (otln(ptbf, j, &ips, &ops, 0))
					return(1);
			}

			/*
			 * pad to end of page
			 */
			if (pln && prtail((lines - pln), 0))
				return(1);

			/*
			 * if EOF go to next file
			 */
			if (cnt < 0)
				break;
			++pagecnt;
		}
		if (inf != stdin)
			(void)fclose(inf);
	}
	if (eoptind < argc)
		return(1);
	return(0);
}
Пример #2
0
/*
 * mulfile:	print files with more than one column of output and
 *		more than one file concurrently
 */
int
mulfile(int argc, char *argv[])
{
	char *ptbf;
	int j;
	int pln;
	int cnt;
	char *lstdat;
	int i;
	FILE **fbuf;
	int actf;
	int lncnt;
	int col;
	int pagecnt;
	int fproc;
	char *buf;
	char *hbuf;
	char *ohbuf;
	const char *fname;
	int ips = 0;
	int cps = 0;
	int ops = 0;
	int mor = 0;

	/*
	 * array of FILE *, one for each operand
	 */
	if ((fbuf = (FILE **)malloc((unsigned)clcnt*sizeof(FILE *))) == NULL) {
		mfail();
		return(1);
	}

	/*
	 * page header
	 */
	if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
		mfail();
		return(1);
	}
	ohbuf = hbuf + offst;

	/*
	 * do not know how many columns yet. The number of operands provide an
	 * upper bound on the number of columns. We use the number of files
	 * we can open successfully to set the number of columns. The operation
	 * of the merge operation (-m) in relation to unsuccesful file opens
	 * is unspecified by posix.
	 */
	j = 0;
	while (j < clcnt) {
		if ((fbuf[j] = nxtfile(argc, argv, &fname, ohbuf, 1)) == NULL)
			break;
		if (pgnm && (inskip(fbuf[j], pgnm, lines)))
			fbuf[j] = NULL;
		++j;
	}

	/*
	 * if no files, exit
	 */
	if (!j)
		return(1);

	/*
	 * calculate page boundries based on open file count
	 */
	clcnt = j;
	if (nmwd) {
		colwd = (pgwd - clcnt - nmwd)/clcnt;
		pgwd = ((colwd + 1) * clcnt) - nmwd - 2;
	} else {
		colwd = (pgwd + 1 - clcnt)/clcnt;
		pgwd = ((colwd + 1) * clcnt) - 1;
	}
	if (colwd < 1) {
		(void)fprintf(err,
		  "pr: page width too small for %d columns\n", clcnt);
		return(1);
	}
	actf = clcnt;
	col = colwd + 1;

	/*
	 * line buffer
	 */
	if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {
		mfail();
		return(1);
	}
	if (offst) {
		(void)memset(buf, (int)' ', offst);
		(void)memset(hbuf, (int)' ', offst);
	}
	if (pgnm)
		pagecnt = pgnm;
	else
		pagecnt = 1;
	lncnt = 0;

	/*
	 * continue to loop while any file still has data
	 */
	while (actf > 0) {
		ttypause(pagecnt);

		/*
		 * loop by line
		 */
		for (i = 0; i < lines; ++i) {
			ptbf = buf + offst;
			lstdat = ptbf;
			if (nmwd) {
				/*
				 * add line number to line
				 */
				addnum(ptbf, nmwd, ++lncnt);
				ptbf += nmwd;
				*ptbf++ = nmchar;
			}
			j = 0;
			fproc = 0;

			/*
			 * loop by column
			 */
			for (j = 0; j < clcnt; ++j) {
				if (fbuf[j] == NULL) {
					/*
					 * empty column; EOF
					 */
					cnt = 0;
				} else if ((cnt = inln(fbuf[j], ptbf, colwd,
							&cps, 1, &mor)) < 0) {
					/*
					 * EOF hit; no data
					 */
					if (fbuf[j] != stdin)
						(void)fclose(fbuf[j]);
					fbuf[j] = NULL;
					--actf;
					cnt = 0;
				} else {
					/*
					 * process file data
					 */
					ptbf += cnt;
					lstdat = ptbf;
					fproc++;
				}

				/*
				 * if last ACTIVE column, done with line
				 */
				if (fproc >= actf)
					break;

				/*
				 * pad to end of column
				 */
				if (sflag) {
					*ptbf++ = schar;
				} else if ((pln = col - cnt) > 0) {
					(void)memset(ptbf, (int)' ', pln);
					ptbf += pln;
				}
			}

			/*
			 * calculate data in line
			 */
			if ((j = lstdat - buf) <= offst)
				break;

			if (!i && !nohead && prhead(hbuf, fname, pagecnt))
				return(1);

			/*
			 * output line
			 */
			if (otln(buf, j, &ips, &ops, 0))
				return(1);

			/*
			 * if no more active files, done
			 */
			if (actf <= 0) {
				++i;
				break;
			}
		}

		/*
		 * pad to end of page
		 */
		if (i && prtail(lines-i, 0))
			return(1);
		++pagecnt;
	}
	if (eoptind < argc)
		return(1);
	return(0);
}
Пример #3
0
/*
 * onecol:	print files with only one column of output.
 *		Line length is unlimited.
 */
int
onecol(int argc, char *argv[])
{
	int cnt = -1;
	int off;
	int lrgln;
	int linecnt;
	int num;
	int lncnt;
	int pagecnt;
	int ips;
	int ops;
	int cps;
	char *obuf;
	char *lbuf;
	char *nbuf;
	char *hbuf;
	char *ohbuf;
	FILE *inf;
	const char *fname;
	int mor;

	if (nmwd)
		num = nmwd + 1;
	else
		num = 0;
	off = num + offst;

	/*
	 * allocate line buffer
	 */
	if ((obuf = malloc((unsigned)(LBUF + off)*sizeof(char))) == NULL) {
		mfail();
		return(1);
	}
	/*
	 * allocate header buffer
	 */
	if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
		mfail();
		return(1);
	}

	ohbuf = hbuf + offst;
	nbuf = obuf + offst;
	lbuf = nbuf + num;
	if (num)
		nbuf[--num] = nmchar;
	if (offst) {
		(void)memset(obuf, (int)' ', offst);
		(void)memset(hbuf, (int)' ', offst);
	}

	/*
	 * loop by file
	 */
	while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
		if (pgnm) {
			/*
			 * skip to specified page
			 */
			if (inskip(inf, pgnm, lines))
				continue;
			pagecnt = pgnm;
		} else
			pagecnt = 1;
		lncnt = 0;

		/*
		 * loop by page
		 */
		for(;;) {
			linecnt = 0;
			lrgln = 0;
			ops = 0;
			ips = 0;
			cps = 0;

			ttypause(pagecnt);

			/*
			 * loop by line
			 */
			while (linecnt < lines) {
				/*
				 * input next line
				 */
				if ((cnt = inln(inf,lbuf,LBUF,&cps,0,&mor)) < 0)
					break;
				if (!linecnt && !nohead &&
					prhead(hbuf, fname, pagecnt))
					return(1);

				/*
				 * start of new line.
				 */
				if (!lrgln) {
					if (num)
						addnum(nbuf, num, ++lncnt);
					if (otln(obuf,cnt+off, &ips, &ops, mor))
						return(1);
				} else if (otln(lbuf, cnt, &ips, &ops, mor))
					return(1);

				/*
				 * if line bigger than buffer, get more
				 */
				if (mor) {
					lrgln = 1;
					continue;
				}

				/*
				 * whole line rcvd. reset tab proc. state
				 */
				++linecnt;
				lrgln = 0;
				ops = 0;
				ips = 0;
			}

			/*
			 * fill to end of page
			 */
			if (linecnt && prtail(lines-linecnt-lrgln, lrgln))
				return(1);

			/*
			 * On EOF go to next file
			 */
			if (cnt < 0)
				break;
			++pagecnt;
		}
		if (inf != stdin)
			(void)fclose(inf);
	}
	if (eoptind < argc)
		return(1);
	return(0);
}
Пример #4
0
/*
 * horzcol:	print files with more than one column of output across a page
 */
int
horzcol(int argc, char *argv[])
{
	char *ptbf;
	int pln;
	int cnt = -1;
	char *lstdat;
	int col = colwd + 1;
	int j;
	int i;
	int lncnt;
	int pagecnt;
	char *buf;
	char *hbuf;
	char *ohbuf;
	const char *fname;
	FILE *inf;
	int ips = 0;
	int cps = 0;
	int ops = 0;
	int mor = 0;

	if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {
		mfail();
		return(1);
	}

	/*
	 * page header
	 */
	if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
		mfail();
		return(1);
	}
	ohbuf = hbuf + offst;
	if (offst) {
		(void)memset(buf, (int)' ', offst);
		(void)memset(hbuf, (int)' ', offst);
	}

	/*
	 * loop by file
	 */
	while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
		if (pgnm) {
			if (inskip(inf, pgnm, lines))
				continue;
			pagecnt = pgnm;
		} else
			pagecnt = 1;
		lncnt = 0;

		/*
		 * loop by page
		 */
		for(;;) {
			ttypause(pagecnt);

			/*
			 * loop by line
			 */
			for (i = 0; i < lines; ++i) {
				ptbf = buf + offst;
				lstdat = ptbf;
				j = 0;
				/*
				 * loop by col
				 */
				for(;;) {
					if (nmwd) {
						/*
						 * add number to column
						 */
						addnum(ptbf, nmwd, ++lncnt);
						ptbf += nmwd;
						*ptbf++ = nmchar;
					}
					/*
					 * input line
					 */
					if ((cnt = inln(inf,ptbf,colwd,&cps,1,
							&mor)) < 0)
						break;
					ptbf += cnt;
					lstdat = ptbf;

					/*
					 * if last line skip padding
					 */
					if (++j >= clcnt)
						break;

					/*
					 * pad to end of column
					 */
					if (sflag)
						*ptbf++ = schar;
					else if ((pln = col - cnt) > 0) {
						(void)memset(ptbf,(int)' ',pln);
						ptbf += pln;
					}
				}

				/*
				 * determine line length
				 */
				if ((j = lstdat - buf) <= offst)
					break;
				if (!i && !nohead &&
					prhead(hbuf, fname, pagecnt))
					return(1);
				/*
				 * output line
				 */
				if (otln(buf, j, &ips, &ops, 0))
					return(1);
			}

			/*
			 * pad to end of page
			 */
			if (i && prtail(lines-i, 0))
				return(1);

			/*
			 * if EOF go to next file
			 */
			if (cnt < 0)
				break;
			++pagecnt;
		}
		if (inf != stdin)
			(void)fclose(inf);
	}
	if (eoptind < argc)
		return(1);
	return(0);
}