Fri, 27 May 2011 15:10:23 +0200
Fixed helpText and removed extra variables for default values
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 "So each file in the working directory is counted. If you want to count C"
69 "\nsource 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 // Get arguments
94 char* directory = "./";
95 char* suffix = " ";
96 bool showHelp = false;
97 char checked = 0;
99 for (int t = 1 ; t < argc ; t++) {
101 int argflags = checkArgument(argv[t], "hsSrRm");
103 // s
104 if ((argflags & 2) > 0) {
105 if ((checked & 1) > 0) {
106 printHelpText(prgName);
107 destroy_settings_t(settings);
108 return 1;
109 }
110 settings->includeSuffixes = true;
111 t++;
112 if (t >= argc) {
113 printHelpText(prgName);
114 destroy_settings_t(settings);
115 return 1;
116 }
117 suffix = argv[t];
118 checked |= 1;
119 }
120 // S
121 if ((argflags & 4) > 0) {
122 if ((checked & 1) > 0) {
123 printHelpText(prgName);
124 destroy_settings_t(settings);
125 return 1;
126 }
127 settings->includeSuffixes = false;
128 t++;
129 if (t >= argc) {
130 printHelpText(prgName);
131 destroy_settings_t(settings);
132 return 1;
133 }
134 suffix = argv[t];
135 checked |= 1;
136 }
137 // h
138 if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) {
139 if ((checked & 2) > 0) {
140 printHelpText(prgName);
141 destroy_settings_t(settings);
142 return 1;
143 }
144 checked |= 2;
145 showHelp = true;
146 }
147 // r, R
148 if ((argflags & 24) > 0) {
149 if ((checked & 4) > 0) {
150 printHelpText(prgName);
151 destroy_settings_t(settings);
152 return 1;
153 }
154 checked |= 4;
155 settings->recursive = true;
156 }
157 if ((argflags & 32) > 0) {
158 if ((checked & 32) > 0) {
159 printHelpText(prgName);
160 destroy_settings_t(settings);
161 return 1;
162 }
163 checked |= 32;
164 settings->matchesOnly = true;
165 }
166 // Path
167 if (argflags == 0) {
168 if ((checked & 8) > 0) {
169 printHelpText(prgName);
170 destroy_settings_t(settings);
171 return 1;
172 }
173 checked |= 8;
174 directory = argv[t];
175 }
176 }
178 // Show help and quit
179 if (showHelp) {
180 printHelpText(prgName);
181 destroy_settings_t(settings);
182 return 0;
183 }
185 // Find tokens
186 char* finder = strtok(suffix, ",");
187 while (finder != NULL) {
188 add_suffix(settings->suffixList, finder);
189 finder = strtok(NULL, ",");
190 }
192 // Open directory
193 DIR *dir = opendir(directory);
194 if (dir == NULL) {
195 perror("Operation failed");
196 destroy_settings_t(settings);
197 return 1;
198 }
200 // Scan directory
201 int lines = scanDirectory(dir, 0, directory, settings);
202 closedir(dir);
203 destroy_settings_t(settings);
205 // Print double line and line count
206 #ifdef _WIN32
207 const int columns = 79;
208 #else
209 const int columns = 80;
210 #endif /* _WIN32 */
212 for (int t = 0 ; t < columns ; t++) {
213 printf("=");
214 }
215 #ifdef _WIN32
216 printf("\n%73d lines\n", lines);
217 #else
218 printf("\n%74d lines\n", lines);
219 #endif /* _WIN32 */
221 return 0;
222 }