cline.c

changeset 0
518bfd1cc1e8
child 1
34a5e235d16e
equal deleted inserted replaced
-1:000000000000 0:518bfd1cc1e8
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdbool.h>
4 #include <stdlib.h>
5 #include <dirent.h>
6
7 static int suffixc;
8 static char** suffixv;
9 static bool recursive;
10 static bool includeSuffixes;
11
12 bool testSuffix(char* filename)
13 {
14 bool ret = false;
15 int tokenlen, fnamelen = strlen(filename);
16 for (int t = 0 ; t < suffixc ; t++)
17 {
18 tokenlen = strlen(suffixv[t]);
19 if (fnamelen >= tokenlen)
20 {
21 if (strncmp(filename+fnamelen-tokenlen, suffixv[t], tokenlen) == 0)
22 {
23 ret = true;
24 break;
25 }
26 }
27 }
28 return ret ^ !includeSuffixes;
29 }
30
31 int scanDirectory(DIR *dir, const int spaces, char* currdir)
32 {
33 DIR *subdir;
34 char* subdirname;
35 struct dirent *entry;
36 int lines, digits, a;
37 int lineSum = 0;
38
39 while ((entry = readdir(dir)) != NULL)
40 {
41 if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)
42 {
43 // Print occurence
44 char entryname[strlen(entry->d_name)+spaces];
45 for (int t = 0 ; t < spaces ; t++)
46 {
47 entryname[t]=' ';
48 }
49 entryname[spaces] = 0;
50 strcat(entryname, entry->d_name);
51 printf("%-60s", entryname);
52
53 // Check for subdirectory
54 char subdirname[(1+strlen(currdir)+strlen(entry->d_name))];
55 strcpy(subdirname, currdir);
56 strcat(subdirname, "/");
57 strcat(subdirname, entry->d_name);
58 if ((subdir = opendir(subdirname)) != NULL)
59 {
60 printf("\n");
61 if (recursive)
62 {
63 lineSum += scanDirectory(subdir, spaces+1, subdirname);
64 }
65 closedir(subdir);
66 continue;
67 }
68
69 // Count lines
70 lines = 0;
71 char filename[(1+strlen(currdir)+strlen(entry->d_name))];
72 strcpy(filename, currdir);
73 strcat(filename, "/");
74 strcat(filename, entry->d_name);
75 if (testSuffix(filename))
76 {
77 FILE *file = fopen(filename, "r");
78 if (file == NULL)
79 {
80 perror(" File acces failed");
81 continue;
82 }
83
84 do
85 {
86 a = fgetc(file);
87
88 if (a == 10)
89 {
90 lines++;
91 }
92 } while (a != EOF);
93 fclose(file);
94
95 // Print line count
96 printf("%14d lines\n", lines);
97
98 lineSum += lines;
99 }
100 else
101 {
102 // Print hint
103 printf("%20s\n", "no match");
104 }
105 }
106 }
107 return lineSum;
108 }
109
110 int main(int argc, char** argv)
111 {
112 // Help text
113 const char* helpText =
114 "\nUsage:\n%s [-h|--help|(-s=<suffix>|-S=<suffix>)|(-r|-R)|<directory>]"
115 "\n\nCounts the line terminator characters (\\n) within all"
116 " files in the specified\ndirectory."
117 "\n\nOptions:"
118 "\n -h, --help - this help text"
119 "\n -s=<suffixes> - only count files with these suffixes (separated"
120 "\n by commas)"
121 "\n -S=<suffixes> - count any file except those with these suffixes"
122 "\n (separated by commas)"
123 "\n -R - excludes subdirectories"
124 "\n -r - includes subdirecotires"
125 "\n\n"
126 "The default call without any options is:"
127 "\n %s -r ./ -S=\n"
128 "That means each file in each subdirectory is counted. If you want to count"
129 "\nC source code in your working directory and its subdirectories, type:"
130 "\n %s -s=.c\n";
131
132 // Program name
133 char* prgName = strrchr(argv[0], '/');
134 if (prgName == NULL)
135 {
136 prgName = argv[0];
137 }
138 else
139 {
140 prgName++;
141 }
142
143 // Defaults
144 char* _suffix = "";
145 char* _directory = "./";
146
147 // Get arguments
148 char* directory;
149 char* suffix;
150 bool showHelp = false;
151 recursive = true;
152 includeSuffixes = false;
153 char checked = 0;
154
155 for (int t = 1 ; t < argc ; t++)
156 {
157 if (strncmp(argv[t], "-s=", 3) == 0)
158 {
159 if ((checked & 1) > 0)
160 {
161 printf(helpText, prgName, prgName, prgName);
162 return -1;
163 }
164 includeSuffixes = true;
165 suffix = argv[t]+3;
166 checked |= 1;
167 }
168 else if (strncmp(argv[t], "-S=", 3) == 0)
169 {
170 if ((checked & 1) > 0)
171 {
172 printf(helpText, prgName, prgName, prgName);
173 return -1;
174 }
175 includeSuffixes = false;
176 suffix = argv[t]+3;
177 checked |= 1;
178 }
179 else if (strcmp(argv[t], "-h") == 0 || strcmp(argv[t], "--help") == 0)
180 {
181 if ((checked & 2) > 0)
182 {
183 printf(helpText, prgName, prgName, prgName);
184 return -1;
185 }
186 checked |= 2;
187 showHelp = true;
188 }
189 else if (strcmp(argv[t], "-r") == 0)
190 {
191 if ((checked & 4) > 0)
192 {
193 printf(helpText, prgName, prgName, prgName);
194 return -1;
195 }
196 checked |= 4;
197 recursive = true;
198 }
199 else if (strcmp(argv[t], "-R") == 0)
200 {
201 if ((checked & 4) > 0)
202 {
203 printf(helpText, prgName, prgName, prgName);
204 return -1;
205 }
206 checked |= 4;
207 recursive = false;
208 }
209 else
210 {
211 if ((checked & 8) > 0)
212 {
213 printf(helpText, prgName, prgName, prgName);
214 return -1;
215 }
216 checked |= 8;
217 directory = argv[t];
218 }
219 }
220
221 // Show help and quit
222 if (showHelp)
223 {
224 printf(helpText, prgName, prgName, prgName);
225 return 0;
226 }
227
228 // Default values
229 if ((checked & 1) == 0)
230 {
231 suffix = _suffix;
232 }
233
234 if ((checked & 8) == 0)
235 {
236 directory = _directory;
237 }
238
239 // Find tokens
240 char* finder;
241 suffixc = 1;
242 finder = strchr(suffix, ',');
243 while (finder != NULL)
244 {
245 suffixc++;
246 finder = strchr(finder+1, ',');
247 }
248 suffixv = (char**) malloc(sizeof(suffixv)*suffixc);
249 if (suffixv == NULL)
250 {
251 fprintf(stderr, "Memory allocation failed.\n");
252 return 1;
253 }
254 finder = strtok(suffix, ",");
255 int c = 0;
256 while (finder != NULL)
257 {
258 suffixv[c] = finder;
259 c++;
260 finder = strtok(NULL, ",");
261 }
262
263 // Open directory
264 DIR *dir = opendir(directory);
265 if (dir == NULL)
266 {
267 perror("Operation failed");
268 free(suffixv);
269 return 1;
270 }
271
272 // Scan directory
273 int lines = scanDirectory(dir, 0, directory);
274
275 // Print double line and line count
276 for (int t = 0 ; t < 80 ; t++)
277 {
278 printf("=");
279 }
280 printf("\n%74d lines\n", lines);
281
282 closedir(dir);
283 free(suffixv);
284 return 0;
285 }

mercurial