Mon, 30 May 2011 08:45:08 +0200
encapsulated common operations
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 exit_with_help(char* prgName, settings_t* settings, int code) {
76 printHelpText(prgName);
77 destroy_settings_t(settings);
78 return code;
79 }
81 int main(int argc, char** argv) {
83 // Settings
84 settings_t *settings = new_settings_t();
85 if (settings == NULL) {
86 fprintf(stderr, "Memory allocation failed.\n");
87 return 1;
88 }
90 // Program name
91 char* prgName = strrchr(argv[0], settings->fileSeparator);
93 if (prgName == NULL) {
94 prgName = argv[0];
95 } else {
96 prgName++;
97 }
99 // Get arguments
100 char* directory = "./";
101 char* suffix = " ";
102 bool showHelp = false;
103 int checked = 0;
105 for (int t = 1 ; t < argc ; t++) {
107 int argflags = checkArgument(argv[t], "hsSrRm");
109 // s
110 if ((argflags & 2) > 0) {
111 if (registerArgument(&checked, 6)) {
112 return exit_with_help(prgName, settings, 1);
113 }
114 settings->includeSuffixes = true;
115 t++;
116 if (t >= argc) {
117 return exit_with_help(prgName, settings, 1);
118 }
119 suffix = argv[t];
120 }
121 // S
122 if ((argflags & 4) > 0) {
123 if (registerArgument(&checked, 6)) {
124 return exit_with_help(prgName, settings, 1);
125 }
126 settings->includeSuffixes = false;
127 t++;
128 if (t >= argc) {
129 return exit_with_help(prgName, settings, 1);
130 }
131 suffix = argv[t];
132 }
133 // h
134 if ((argflags & 1) > 0 || strcmp(argv[t], "--help") == 0) {
135 if (registerArgument(&checked, 1)) {
136 return exit_with_help(prgName, settings, 1);
137 }
138 showHelp = true;
139 }
140 // r, R
141 if ((argflags & 24) > 0) {
142 if (registerArgument(&checked, 24)) {
143 return exit_with_help(prgName, settings, 1);
144 }
145 settings->recursive = true;
146 }
147 // m
148 if ((argflags & 32) > 0) {
149 if (registerArgument(&checked, 32)) {
150 return exit_with_help(prgName, settings, 1);
151 }
152 settings->matchesOnly = true;
153 }
154 // Path
155 if (argflags == 0) {
156 if (registerArgument(&checked, 1024)) {
157 return exit_with_help(prgName, settings, 1);
158 }
159 directory = argv[t];
160 }
161 }
163 // Show help and quit
164 if (showHelp) {
165 return exit_with_help(prgName, settings, 0);
166 }
168 // Find tokens
169 char* finder = strtok(suffix, ",");
170 while (finder != NULL) {
171 add_suffix(settings->suffixList, finder);
172 finder = strtok(NULL, ",");
173 }
175 // Open directory
176 DIR *dir = opendir(directory);
177 if (dir == NULL) {
178 perror("Operation failed");
179 destroy_settings_t(settings);
180 return 1;
181 }
183 // Scan directory
184 int lines = scanDirectory(dir, 0, directory, settings);
185 closedir(dir);
186 destroy_settings_t(settings);
188 // Print double line and line count
189 #ifdef _WIN32
190 const int columns = 79;
191 #else
192 const int columns = 80;
193 #endif /* _WIN32 */
195 for (int t = 0 ; t < columns ; t++) {
196 printf("=");
197 }
198 #ifdef _WIN32
199 printf("\n%73d lines\n", lines);
200 #else
201 printf("\n%74d lines\n", lines);
202 #endif /* _WIN32 */
204 return 0;
205 }