1
0
Files
irix-657m-src/eoe/cmd/vi/misc/fold.c
2022-09-29 17:59:04 +03:00

501 lines
10 KiB
C

/*
* Copyright 1995, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
*
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
* GRAPHICS, INC.
*/
/*
* fold.c
*
*/
#ident "$Revision: 1.3 $"
#include <sys/euc.h>
#include <getwidth.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <locale.h>
#include <pfmt.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#define IDENTICAL(A,B) (A.st_dev==B.st_dev && A.st_ino==B.st_ino)
#define MAX_ZERO_WR 5
int DEBUG = 0;
#define PRINTD if (DEBUG) printf
int width = 80;
int pick_width = 0;
int break_at_space = 0;
int errnbr = 0;
int S_FLAG = 0;
int old_fold = 0;
int new_fold = 0;
int old_width = 80;
/* Holds info about the character set */
eucwidth_t wp;
char badwrite[] = ":1:Write error: %s\n";
char outputerror[] = "uxsgicore:4:Output error: %s\n";
char inputerror[] = "uxsgicore:5:Input error: %s (%s)\n";
void flush_at_space (char *this_line, int last_space, int *buf_chars, int *line_chars);
void flush_line(char *line, int len);
void readerr(char *filename);
void putch(int c);
main(int argc, char **argv)
{
register FILE *fi;
register int c;
extern int optind;
extern char *optarg;
int i, count;
int errflg = 0;
int stdinflg = 0;
struct stat64 source, target;
char *widthstring;
int status = 0;
(void)setlocale(LC_ALL, "");
(void)setcat("uxcore.abi");
(void)setlabel("UX:fold");
/* getwidth(&wp);*/
/*
for (i = 0; i < argc; i++)
printf ("opt %d: %s\n", i, argv[i]);
*/
while( (c=getopt(argc,argv,"0123456789dsbw:")) != EOF ) {
switch(c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (new_fold) {
pfmt(stderr, MM_ACTION, ":2:Usage: fold -bs [-w width] [file ...] ...\n");
exit(2);
}
old_fold = 1;
old_width *= 10;
old_width += c - '0';
continue;
case 'd':
DEBUG = 1;
continue;
case 'w':
if (old_fold) {
printf("Bad number for fold\n");
exit(1);
}
new_fold = 1;
pick_width = 1;
widthstring = optarg;
if (!isdigit(optarg[0]))
errflg++;
width = atoi(widthstring);
continue;
case 'b':
if (old_fold) {
printf("Bad number for fold\n");
exit(1);
}
new_fold = 1;
continue;
case 's':
if (old_fold) {
printf("Bad number for fold\n");
exit(1);
} new_fold = 1;
break_at_space++;
continue;
case '?':
errflg++;
break;
}
}
if (!new_fold) {
width = old_width;
if (!width) {
printf("Bad number for fold\n");
exit(1);
}
argc = argc - optind;
argv = &argv[optind];
do {
if (argc > 0) {
if (freopen(argv[0], "r", stdin) == NULL) {
perror(argv[0]);
exit(1);
}
argc--, argv++;
}
for (;;) {
c = getc(stdin);
if (c == -1)
break;
putch(c);
}
} while (argc > 0);
exit(0);
}
if (errflg) {
pfmt(stderr, MM_ACTION, ":2:Usage: fold -b [-w width] [file ...] ...\n");
exit(2);
}
/*
* Stat stdout to be sure it is defined.
*/
if(fstat64(fileno(stdout), &target) < 0) {
pfmt(stderr, MM_ERROR, ":3:Cannot access stdout: %s\n",strerror(errno));
exit(2);
}
/*
* If no arguments given, then use stdin for input.
*/
if (optind == argc) {
argc++;
stdinflg++;
}
/*
* Process each remaining argument,
* unless there is an error with stdout.
*/
for (argv = &argv[optind];
optind < argc && !ferror(stdout); optind++, argv++) {
/*
* If the argument was '-' or there were no files
* specified, take the input from stdin.
*/
if (stdinflg
||((*argv)[0]=='-'
&& (*argv)[1]=='\0'))
fi = stdin;
else {
/*
* Attempt to open each specified file.
*/
if ((fi = fopen(*argv, "r")) == NULL) {
pfmt(stderr, MM_ERROR, ":4:Cannot open %s: %s\n",
*argv, strerror(errno));
exit(2);
PRINTD("Exit failed\n");
}
}
/*
* Stat source to make sure it is defined.
*/
if(fstat64(fileno(fi), &source) < 0) {
pfmt(stderr, MM_ERROR, ":5:Cannot access %s: %s\n",
*argv, strerror(errno));
status = 2;
continue;
}
/*
* If the source is not a character special file or a
* block special file, make sure it is not identical
* to the target.
*/
if (!S_ISCHR(target.st_mode)
&& !S_ISBLK(target.st_mode)
&& IDENTICAL(target, source)) {
pfmt(stderr, MM_ERROR,
":6:Input/output files '%s' identical\n",
stdinflg?"-": *argv);
if (fclose(fi) != 0 )
pfmt(stderr, MM_ERROR, badwrite, strerror(errno));
status = 2;
continue;
}
/*
* If in visible mode, use vcat; otherwise, use cat.
*/
if (break_at_space) {
status = fold_at_space(*argv,fi);
} else {
status = fold(*argv,fi);
}
/*
* If the input is not stdin, flush stdout.
*/
if (fi!=stdin) {
fflush(stdout);
/*
* Attempt to close the source file.
*/
if (fclose(fi) != 0)
pfmt(stderr, MM_ERROR, badwrite, strerror(errno));
}
}
}
void flush_line(char *line, int len)
{
int i;
for(i = 0; i < len; i++)
putchar(line[i]);
}
/* May need to use no_new_line here too*/
fold_at_space(filename,fi)
char *filename;
FILE *fi;
{
register int c;
int i;
int line_chars = 0;
int buf_chars = 0;
char *this_line;
int last_space = -1;
int no_new_line = 0;
this_line = (char *) calloc (width + 1, sizeof(char));
while ((c = getc(fi)) != EOF) {
switch (c) {
case '\t':
this_line[buf_chars++] = c;
line_chars = line_chars - (line_chars % 8) + 8;
if (line_chars >= width + 1) {
flush_line(this_line, buf_chars-1);
putchar('\n');
buf_chars = 0;
this_line[buf_chars++] = '\t';
last_space = 0;
line_chars = 8;
} else {
last_space = buf_chars - 1;
}
continue;
case '\b':
if (line_chars == 0) {
putchar('\b');
} else {
this_line[buf_chars++] = c;
line_chars++;
if (line_chars == width + 1) {
flush_at_space(this_line, last_space, &buf_chars, &line_chars);
last_space = -1;
}
}
continue;
case '\n':
flush_line(this_line, buf_chars);
bzero(this_line, (width + 1) * sizeof(char));
putchar('\n');
buf_chars = 0;
line_chars = 0;
last_space = -1;
continue;
case ' ':
PRINTD("Got space, last_space: %d\n", last_space);
this_line[buf_chars++] = c;
line_chars++;
if (line_chars == width + 1) {
flush_at_space(this_line, last_space, &buf_chars, &line_chars);
last_space = 0;
} else {
last_space = buf_chars - 1;
}
continue;
default:
this_line[buf_chars++] = c;
line_chars++;
if (line_chars == width + 1) {
flush_at_space(this_line, last_space, &buf_chars, &line_chars);
last_space = -1;
}
continue;
}
}
return(0);
}
void flush_at_space (char *this_line, int last_space, int *buf_chars, int *line_chars)
{
int i;
int bch = *buf_chars;
if (last_space == -1) {
for (i = 0; i < bch-1; i++)
putchar(this_line[i]);
putchar('\n');
this_line[0] = this_line[bch-1];
*line_chars = 1;
*buf_chars = 1;
} else {
PRINTD ("last_space: %d, line_chars: %d", last_space, *line_chars);
for (i = 0; i < last_space + 1; i++)
putchar(this_line[i]);
putchar('\n');
*line_chars = 0;
*buf_chars = 0;
for (i = last_space + 1; i < bch; i++) {
this_line[(*buf_chars)++] = this_line[i];
*line_chars += (this_line[i] == '\t') ? (8 - (*line_chars % 8)) : 1;
}
}
}
fold(filename,fi)
char *filename;
FILE *fi;
{
int line_chars = 0;
register int c;
int new_line_ok = 1;
while ((c = getc(fi)) != EOF) {
switch (c) {
case '\t':
putchar(c);
line_chars = line_chars - (line_chars % 8) + 8;
if (line_chars == width) {
putchar('\n');
new_line_ok = 0;
line_chars = 0;
} else {
new_line_ok = 1;
}
continue;
case '\n':
if (new_line_ok) {
putchar(c);
line_chars = 0;
} else {
new_line_ok = 1;
}
continue;
case '\b':
if (new_line_ok == 0) {
new_line_ok = 1;
} else {
putchar(c);
if (line_chars != 0) {
line_chars++;
if (line_chars == width) {
putchar('\n');
line_chars = 0;
new_line_ok = 0;
}
} else {
new_line_ok = 1;
}
}
continue;
default:
putchar(c);
line_chars++;
if (line_chars == width) {
putchar('\n');
line_chars = 0;
new_line_ok = 0;
} else {
new_line_ok = 1;
}
continue;
}
}
return(0);
}
void readerr(filename)
char *filename;
{
if(filename==(char *)NULL)
pfmt(stderr, MM_ERROR, inputerror, strerror(errno), "stdin");
else
pfmt(stderr, MM_ERROR, inputerror, strerror(errno), filename);
}
int col;
void putch(c)
register c;
{
register ncol;
switch (c) {
case '\n':
ncol = 0;
break;
case '\t':
ncol = (col + 8) &~ 7;
break;
case '\b':
ncol = col ? col - 1 : 0;
break;
case '\r':
ncol = 0;
break;
default:
ncol = col + 1;
}
if (ncol > width)
putchar('\n'), col = 0;
putchar(c);
switch (c) {
case '\n':
col = 0;
break;
case '\t':
col += 8;
col &= ~7;
break;
case '\b':
if (col)
col--;
break;
case '\r':
col = 0;
break;
default:
col++;
break;
}
}