Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/ncsl/ncsl.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1994-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
/*
23
* Glenn Fowler
24
* AT&T Research
25
*
26
* ncsl [file ...]
27
*
28
* ncsl -- list the number of non-comment source lines for each C file
29
*/
30
31
static const char usage[] =
32
"[-?\n@(#)$Id: ncsl (AT&T Research) 1996-10-11 $\n]"
33
USAGE_LICENSE
34
"[+NAME?ncsl - list the number of non-comment source lines for each C file]"
35
"[+DESCRIPTION?\bncsl\b lists the number of non-comment source lines for"
36
" each C \afile\a argument. If no \afile\a arguments are specified then"
37
" the standard input is read. /*...*/ and // style comments are"
38
" recognized.]"
39
40
"[s:summary?If more than one \afile\a is specified then list a summary count"
41
" for all files.]"
42
43
"\n"
44
"\n[ file ... ]\n"
45
"\n"
46
47
"[+SEE ALSO?\bwc\b(1)]"
48
;
49
50
#include <ast.h>
51
#include <ctype.h>
52
#include <error.h>
53
54
#define JUNK(c) (iscntrl(c)||!isprint(c))
55
56
/*
57
* return number of ncsl in sp
58
*/
59
60
static int
61
ncsl(register Sfio_t* sp)
62
{
63
register int c;
64
register int data;
65
register unsigned long line;
66
int quote;
67
68
line = 0;
69
data = 0;
70
again:
71
for (;;) switch (c = sfgetc(sp))
72
{
73
case EOF:
74
return(line);
75
case ' ':
76
case '\f':
77
case '\t':
78
break;
79
case '\n':
80
newline:
81
if (data)
82
{
83
if (data > 0) line++;
84
data = 0;
85
}
86
break;
87
case '/':
88
if (data < 0) goto again;
89
switch (c = sfgetc(sp))
90
{
91
case '/':
92
for (;;) switch (c = sfgetc(sp))
93
{
94
case EOF:
95
goto again;
96
case '\n':
97
goto newline;
98
default:
99
if (JUNK(c))
100
{
101
data = -1;
102
goto again;
103
}
104
break;
105
}
106
break;
107
case '*':
108
for (;;) switch (c = sfgetc(sp))
109
{
110
case EOF:
111
case '*':
112
for (;;)
113
{
114
switch (c = sfgetc(sp))
115
{
116
case EOF:
117
case '/':
118
goto again;
119
case '*':
120
continue;
121
default:
122
if (JUNK(c))
123
{
124
data = -1;
125
goto again;
126
}
127
break;
128
}
129
break;
130
}
131
break;
132
default:
133
if (JUNK(c))
134
{
135
data = -1;
136
goto again;
137
}
138
break;
139
}
140
break;
141
case EOF:
142
break;
143
default:
144
if (!data) data = 1;
145
sfungetc(sp, c);
146
break;
147
}
148
break;
149
case '"':
150
case '\'':
151
if (data < 0) goto again;
152
data = 1;
153
quote = c;
154
for (;;) switch (c = sfgetc(sp))
155
{
156
case EOF:
157
goto again;
158
case '"':
159
case '\'':
160
if (c == quote) goto again;
161
break;
162
case '\n':
163
goto newline;
164
case '\\':
165
switch (c = sfgetc(sp))
166
{
167
case EOF:
168
goto again;
169
case '\n':
170
line++;
171
continue;
172
}
173
/*FALLTHROUGH*/
174
default:
175
if (JUNK(c))
176
{
177
data = -1;
178
goto again;
179
}
180
break;
181
}
182
break;
183
default:
184
if (JUNK(c)) data = -1;
185
else if (!data) data = 1;
186
break;
187
}
188
/*NOTREACHED*/
189
}
190
191
int
192
main(int argc, char** argv)
193
{
194
register char* s;
195
register Sfio_t* sp;
196
197
unsigned long n;
198
int summary = 0;
199
unsigned long total = 0;
200
int trailer;
201
202
NoP(argc);
203
error_info.id = "ncsl";
204
for (;;)
205
{
206
switch (optget(argv, usage))
207
{
208
case 0:
209
break;
210
case 's':
211
summary = 1;
212
continue;
213
case '?':
214
error(ERROR_USAGE|4, "%s", opt_info.arg);
215
continue;
216
case ':':
217
error(2, "%s", opt_info.arg);
218
continue;
219
}
220
break;
221
}
222
argv += opt_info.index;
223
if (error_info.errors)
224
error(ERROR_USAGE|4, "%s", optusage(NiL));
225
if (*argv)
226
{
227
trailer = *(argv + 1) != 0;
228
while (s = *argv++)
229
{
230
if (!(sp = sfopen(NiL, s, "r")))
231
error(2, "%s: cannot open for reading", s);
232
else
233
{
234
n = ncsl(sp);
235
sfclose(sp);
236
if (!summary)
237
sfprintf(sfstdout, "%s: %lu\n", s, n);
238
total += n;
239
}
240
}
241
if (summary || trailer)
242
sfprintf(sfstdout, "%lu\n", total);
243
}
244
else
245
sfprintf(sfstdout, "%d\n", ncsl(sfstdin));
246
return error_info.errors != 0;
247
}
248
249