summaryrefslogtreecommitdiff
path: root/support/RTF-1_06a1/rtfwc.c
blob: 30d58e1cfe48b5a25855d2b1bf46033d29f5ca45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
	rtfwc - read rtf input, write word count (actually, char, word
		and paragraph counts).

	This installs callbacks for the ascii and control token classes.
	The control class is necessary so that special characters such as
	\par, \tab, \sect, etc.  can be counted.

	Counts paragraphs instead of lines, since the concept of "line"
	is relatively meaningless.

	It's problematic how to count text in headers and footers, and
	what to do about tables.

	04 Feb 91	Paul DuBois	dubois@primate.wisc.edu

	04 Feb 91 V1.0. Created.
	27 Feb 91 V1.01. Updated for distribution 1.05.
	16 Mar 91 V1.02. Updated for distribution 1.06.  Multiple files
		allowed.
*/

# include	<stdio.h>
# include	"rtf.h"


static long	chars, tchars = 0;
static long	words, twords = 0;
static long	paras, tparas = 0;
static long	wchars = 0;	/* chars in current word */

static void	Count ();
static void	Text ();
static void	Control ();

int main (argc, argv)
int	argc;
char	**argv;
{
int	i;

	--argc;
	++argv;

	if (argc == 0)
	{
		Count ();
		printf ("\n");
	}
	else
	{
		for (i = 0; i < argc; i++)
		{
			if (freopen (argv[i], "r", stdin) == NULL)
			{
				fprintf (stderr, "Can't open \"%s\"\n",
								argv[i]);
				exit (1);
			}
			Count ();
			printf ("\t%s\n", argv[i]);
		}
		if (argc > 1)	/* multiple files, print totals */
			printf ("%ld chars\t%ld words\t%ld paragraphs\ttotal\n",
						tchars, twords, tparas);
	}

	exit (0);
}


static void Count ()
{
	chars = words = paras = wchars = 0;

	RTFInit ();

	/* install counting hooks and process the input stream */

	RTFSetClassCallback (rtfText, Text);
	RTFSetClassCallback (rtfControl, Control);
	RTFRead ();
	printf ("%ld chars\t%ld words\t%ld paragraphs", chars, words, paras);
	tchars += chars;
	twords += words;
	tparas += paras;
}

static void Text ()
{
	++chars;
	if (rtfMajor != ' ')
		++wchars;
	else if (wchars > 0)
		++words;
}


static void Control ()
{
	if (rtfMajor != rtfSpecialChar)
		return;
	switch (rtfMinor)
	{
	case rtfPage:
	case rtfSect:
	case rtfLine:
	case rtfPar:
		++paras;
		++chars;
		if (wchars > 0)
		{
			++words;
			wchars = 0;
		}
		break;
	case rtfNoBrkSpace:
	case rtfTab:
		++chars;
		if (wchars > 0)
		{
			++words;
			wchars = 0;
		}
		break;
	case rtfNoBrkHyphen:
		++chars;
		++wchars;
		break;
	}
}