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

307 lines
6.4 KiB
C

/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */
/* UNIX System Laboratories, Inc. */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* #ident "@(#)wc:wc.c 1.5" */
#ident "$Header: /proj/irix6.5.7m/isms/eoe/cmd/wc/RCS/wc.c,v 1.17 1997/01/12 23:17:59 danc Exp $"
/*
** wc -- word and line count
*/
#include <stdio.h>
#include <stdlib.h> /* for i18n */
#include <wctype.h> /* for i18n */
#include <ctype.h> /* for isgraph def */
#include <locale.h>
#include <pfmt.h>
#include <errno.h>
#include <string.h>
#include <limits.h> /* for i18n */
#define OPTBUFSIZ 20
char b[BUFSIZ];
FILE *fptr = stdin;
long long wordct;
long long twordct=0;
long long linect;
long long tlinect=0;
long long charct;
long long tcharct=0;
long long bytect;
long long tbytect=0;
extern int errno;
extern char *sys_errlist[];
#define STR_CLONE(A, B) { if (A) free(A); A = strdup(B); }
void wcp(char *, long long, long long, long long, long long);
void nomem(void);
int
main(
int argc,
char **argv
)
{
char *p1, *p2;
unsigned int c;
int i, token;
int status = 0;
char *wd; /* this string contains all wc options */
char *begin_wd, *tmp_wd;
char buffer[OPTBUFSIZ]; /* to store options */
int index;
int charlength; /* i18n */
wchar_t wchar_c; /* i18n */
wchar_t *pwc;
long long char_index;
int byte_cnt;
int begin_wdsz;
(void)setlocale(LC_ALL, "");
(void)setcat("uxcore");
(void)setlabel("UX:wc");
wd = strdup("lwc"); /* default is: newlines, words, bytes */
if(!wd) nomem();
/* case where there is only one "grouped" option like -wc, -wlc etc.. */
/* or case where there are separate options */
index = 1;
if ( (argc>=2) && (*argv[index]=='-') ) {
STR_CLONE(wd, "");
if(!wd) nomem();
begin_wd = wd;
begin_wdsz = (strlen(wd) + 1);
while (index < argc) {
if (*argv[index]=='-') {
++argv[index];
if (*argv[index]!='-') {
/*
* See if this string will overflow
* the current malloc'ed string space.
* If so, then calloc another string
* space which will be able to hold
* the old string plus the new one and
* then copy the old and concatenate
* the new one.
*/
if((strlen(argv[index]) +
strlen(begin_wd)) >
(begin_wdsz - 1))
{
tmp_wd =
(char *)calloc((size_t)1,
(size_t)(begin_wdsz +
strlen(argv[index]) + 2));
if(!tmp_wd) {
free(begin_wd);
nomem();
}
begin_wdsz = (begin_wdsz +
strlen(argv[index]) + 2);
wd = tmp_wd;
strcat(tmp_wd , begin_wd);
free(begin_wd); /* free old */
begin_wd = wd;
}
strcat(wd , argv[index]);
wd = begin_wd;
}
else { /* -- terminates the options */
argc-=index;
argv+=index;
if (!strlen(wd)) {
STR_CLONE(wd, "lwc");
}
if(!wd) nomem();
begin_wdsz = (strlen(wd) + 1);
begin_wd = wd;
break;
}
}
if ( (index+1) < argc ) {
if (*argv[index+1]!='-') {
argc-=index;
argv+=index;
break;
}
else index++;
}
else {
argc-=index;
argv+=index;
break;
}
}
}
/* usr strstr to find what options are in wd and reorder them */
/* (the "newlines, words, chars/bytes" order always holds) */
if (strlen(wd) < OPTBUFSIZ) {
strcpy(buffer, wd);
STR_CLONE(wd, "lwc");
if(!wd) nomem();
*wd = *(wd+1) = *(wd+2) = 0;
if (strstr(buffer,"l")) strcat(wd,"l");
if (strstr(buffer,"w")) strcat(wd,"w");
if (strstr(buffer,"c")) strcat(wd,"c");/* c or m, not both */
else if (strstr(buffer,"m")) strcat(wd,"m");
}
else STR_CLONE(wd, "lwc");
if(!wd) nomem();
i = 1;
do { /* for each file given as argument */
if(argc>1 && (fptr=fopen(argv[i], "r")) == NULL) {
pfmt(stderr, MM_ERROR, ":92:Cannot open %s: %s\n",
argv[i], strerror(errno));
status = 2;
continue;
}
p1 = p2 = b; /* beginning of buffer */
linect = 0;
wordct = 0;
charct = 0;
token = 0;
bytect = 0;
for(;;) { /* for each character */
if(p1 >= p2) { /* done for each page buffer */
p1 = b;
if (feof(fptr)) /* EOF */
break;
c = fread(p1, 1, BUFSIZ, fptr);
if(c <= 0)
break;
bytect += c;
p2 = p1+c; /* end of buffer */
}
if (MB_CUR_MAX > 1) {
byte_cnt = mbtowc(&wchar_c, p1, (size_t) MB_CUR_MAX);
if (byte_cnt <= 0) {
p1++; /* skip the NULL */
}
else { charct ++;
p1 += byte_cnt; /* move to the next char*/
if(iswgraph(wchar_c)) {
if(!token) {
wordct++;
token++;
}
continue;
}
if(wchar_c == L'\n')
linect++;
else if(!iswspace(wchar_c) &&
wchar_c != L'\t')
continue;
token = 0;
}
}
else { c = *p1++;
charct ++;
if(isgraph(c)) {
if(!token) {
wordct++;
token++;
}
continue;
}
if(c == '\n') linect++;
else if(!isspace(c)) continue;
token = 0;
}
} /* "for each character" loop */
#ifdef sgi
if (ferror(fptr)) {
if (argc > 1)
fprintf(stderr, "wc: %s: read failed (%s)\n",
argv[i], sys_errlist[errno]);
else
fprintf(stderr, "wc: read failed (%s)\n",
sys_errlist[errno]);
fclose(fptr);
status = 2;
continue;
}
#endif
/* print lines, words, chars */
wcp(wd, bytect, charct, wordct, linect);
if(argc>1) {
printf(" %s\n", argv[i]);
}
else
printf("\n");
fclose(fptr);
tlinect += linect;
twordct += wordct;
tcharct += charct;
tbytect += bytect;
} while(++i<argc);
if(argc > 2) {
wcp(wd, tbytect, tcharct, twordct, tlinect);
pfmt(stdout, MM_NOSTD, ":551: total\n");
}
if(wd) free(wd);
exit(status);
}
void
wcp(
char *wd,
long long bytect,
long long charct,
long long wordct,
long long linect
)
{
char *wdp = wd;
while(*wdp) {
switch(*wdp++) {
case 'l':
printf("%14lld", linect);
break;
case 'w':
printf("%14lld", wordct);
break;
case 'c':
printf("%14lld", bytect);
break;
case 'm':
printf("%14lld", charct);
break;
default:
pfmt(stderr, MM_ERROR, ":1:Incorrect usage\n");
pfmt(stderr, MM_ACTION,
":552:Usage: wc [-clw] [name ...]\n");
exit(2);
}
}
}
void
nomem()
{
fprintf(stderr, "wc: ");
pfmt(stderr, MM_ERROR, ":725:out of memory\n");
exit(2);
}