Fri, 27 May 2011 14:45:16 +0200
encapsulated suffix list in type suffix_list_t
1 #include "cline.h"
2 #include "functions.h"
4 suffix_list_t* new_suffix_list_t() {
5 suffix_list_t* suffixList = malloc(sizeof(suffix_list_t*));
6 suffixList->count = 0;
7 suffixList->items = NULL;
8 }
10 void destroy_suffix_list_t(suffix_list_t* list) {
11 while (--list->count >= 0) {
12 free(list->items[list->count]);
13 }
14 free(list);
15 }
17 void add_suffix(suffix_list_t* list, char* item) {
18 char** reallocated_list =
19 realloc(list->items, sizeof(char**) * list->count + 1);
20 if (reallocated_list != NULL) {
21 list->items = reallocated_list;
22 list->items[list->count] = item;
23 list->count++;
24 }
25 }
27 settings_t* new_settings_t() {
28 settings_t *settings = malloc(sizeof(settings_t*));
29 if (settings != NULL) {
30 #ifdef _WIN32
31 settings->fileSeparator = '\\';
32 #else
33 settings->fileSeparator = '/';
34 #endif /* _WIN32 */
35 settings->recursive = false;
36 settings->includeSuffixes = false;
37 settings->matchesOnly = false;
38 settings->suffixList = new_suffix_list_t();
39 }
41 return settings;
42 }
44 void destroy_settings_t(settings_t* settings) {
45 destroy_suffix_list_t(settings->suffixList);
46 free(settings);
47 }
49 void printHelpText(const char* prgName) {
50 // Help text
51 const char* helpText =
52 "\nUsage:"
53 "\n %s [-hrm][-s suffix][<directory>]"
54 "\n %s [-hrm][-S suffix][<directory>]"
55 "\n\nCounts the line terminator characters (\\n) within all"
56 " files in the specified\ndirectory."
57 "\n\nOptions:"
58 "\n -h, --help - this help text"
59 "\n -m - print information about matching files only"
60 "\n -s <suffixes> - only count files with these suffixes (separated"
61 "\n by commas)"
62 "\n -S <suffixes> - count any file except those with these suffixes"
63 "\n (separated by commas)"
64 "\n -r, -R - includes subdirectories"
65 "\n\n"
66 "The default call without any options is:"
67 "\n %s ./\n"
68 "That means each file in each subdirectory is counted. If you want to count"
69 "\nC source code in your working directory and its subdirectories, type:"
70 "\n %s -rs .c\n";
72 printf(helpText, prgName, prgName, prgName, prgName);
73 }
75 int main(int argc, char** argv) {
77 // Settings
78 settings_t *settings = new_settings_t();
79 if (settings == NULL) {
80 fprintf(stderr, "Memory allocation failed.\n");
81 return 1;
82 }
84 // Program name
85 char* prgName = strrchr(argv[0], settings->fileSeparator);
87 if (prgName == NULL) {
88 prgName = argv[0];
89 } else {
90 prgName++;
91 }
93 // Defaults
94 char* _suffix = " ";
95 char _directory[3];
96 _directory[0] = '.';
97 _directory[1] = settings->fileSeparator;
98 _directory[2] = 0;
100 // Get arguments
101 char* directory;
102 char* suffix;
103 bool showHelp = false;
104 char checked = 0;
106 for (int t = 1 ; t < argc ; t++) {
108 int argflags = checkArgument(argv[t], "hsSrRm");
110 // s
111 if ((argflags & 2) > 0) {
112 if ((checked & 1) > 0) {
113 printHelpText(prgName);
114 destroy_settings_t(settings);
115 return 1;
116 }
117 settings->includeSuffixes = true;
118 t++;
119 if (t >= argc) {
120 printHelpText(prgName);
121 destroy_settings_t(settings);
122 return 1;
123 }
124 suffix = argv[t];
125 checked |= 1;
126 }
127 // S
128 if ((argflags & 4) > 0) {
129 if ((checked & 1) > 0) {
130 printHelpText(prgName);
131 destroy_settings_t(settings);
132 return 1;
133 }
134 settings->includeSuffixes = false;
135 t++;
136 if (t >= argc) {
137 printHelpText(prgName);
138 destroy_settings_t(settings);
139 return 1;
140 }
141 suffix = argv[t];
142 checked |= 1;
143 }
144 // h
145 if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) {
146 if ((checked & 2) > 0) {
147 printHelpText(prgName);
148 destroy_settings_t(settings);
149 return 1;
150 }
151 checked |= 2;
152 showHelp = true;
153 }
154 // r, R
155 if ((argflags & 24) > 0) {
156 if ((checked & 4) > 0) {
157 printHelpText(prgName);
158 destroy_settings_t(settings);
159 return 1;
160 }
161 checked |= 4;
162 settings->recursive = true;
163 }
164 if ((argflags & 32) > 0) {
165 if ((checked & 32) > 0) {
166 printHelpText(prgName);
167 destroy_settings_t(settings);
168 return 1;
169 }
170 checked |= 32;
171 settings->matchesOnly = true;
172 }
173 // Path
174 if (argflags == 0) {
175 if ((checked & 8) > 0) {
176 printHelpText(prgName);
177 destroy_settings_t(settings);
178 return 1;
179 }
180 checked |= 8;
181 directory = argv[t];
182 }
183 }
185 // Show help and quit
186 if (showHelp) {
187 printHelpText(prgName);
188 destroy_settings_t(settings);
189 return 0;
190 }
192 // Default values
193 if ((checked & 1) == 0) {
194 suffix = _suffix;
195 }
197 if ((checked & 8) == 0) {
198 directory = _directory;
199 }
201 // Find tokens
202 char* finder = strtok(suffix, ",");
203 while (finder != NULL) {
204 add_suffix(settings->suffixList, finder);
205 finder = strtok(NULL, ",");
206 }
208 // Open directory
209 DIR *dir = opendir(directory);
210 if (dir == NULL) {
211 perror("Operation failed");
212 destroy_settings_t(settings);
213 return 1;
214 }
216 // Scan directory
217 int lines = scanDirectory(dir, 0, directory, settings);
218 closedir(dir);
220 // Print double line and line count
221 #ifdef _WIN32
222 const int columns = 79;
223 #else
224 const int columns = 80;
225 #endif /* _WIN32 */
227 for (int t = 0 ; t < columns ; t++) {
228 printf("=");
229 }
230 #ifdef _WIN32
231 printf("\n%73d lines\n", lines);
232 #else
233 printf("\n%74d lines\n", lines);
234 #endif /* _WIN32 */
236 destroy_settings_t(settings);
238 return 0;
239 }