1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/cline.c Mon May 23 16:42:44 2011 +0200 1.3 @@ -0,0 +1,285 @@ 1.4 +#include <stdio.h> 1.5 +#include <string.h> 1.6 +#include <stdbool.h> 1.7 +#include <stdlib.h> 1.8 +#include <dirent.h> 1.9 + 1.10 +static int suffixc; 1.11 +static char** suffixv; 1.12 +static bool recursive; 1.13 +static bool includeSuffixes; 1.14 + 1.15 +bool testSuffix(char* filename) 1.16 +{ 1.17 + bool ret = false; 1.18 + int tokenlen, fnamelen = strlen(filename); 1.19 + for (int t = 0 ; t < suffixc ; t++) 1.20 + { 1.21 + tokenlen = strlen(suffixv[t]); 1.22 + if (fnamelen >= tokenlen) 1.23 + { 1.24 + if (strncmp(filename+fnamelen-tokenlen, suffixv[t], tokenlen) == 0) 1.25 + { 1.26 + ret = true; 1.27 + break; 1.28 + } 1.29 + } 1.30 + } 1.31 + return ret ^ !includeSuffixes; 1.32 +} 1.33 + 1.34 +int scanDirectory(DIR *dir, const int spaces, char* currdir) 1.35 +{ 1.36 + DIR *subdir; 1.37 + char* subdirname; 1.38 + struct dirent *entry; 1.39 + int lines, digits, a; 1.40 + int lineSum = 0; 1.41 + 1.42 + while ((entry = readdir(dir)) != NULL) 1.43 + { 1.44 + if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) 1.45 + { 1.46 + // Print occurence 1.47 + char entryname[strlen(entry->d_name)+spaces]; 1.48 + for (int t = 0 ; t < spaces ; t++) 1.49 + { 1.50 + entryname[t]=' '; 1.51 + } 1.52 + entryname[spaces] = 0; 1.53 + strcat(entryname, entry->d_name); 1.54 + printf("%-60s", entryname); 1.55 + 1.56 + // Check for subdirectory 1.57 + char subdirname[(1+strlen(currdir)+strlen(entry->d_name))]; 1.58 + strcpy(subdirname, currdir); 1.59 + strcat(subdirname, "/"); 1.60 + strcat(subdirname, entry->d_name); 1.61 + if ((subdir = opendir(subdirname)) != NULL) 1.62 + { 1.63 + printf("\n"); 1.64 + if (recursive) 1.65 + { 1.66 + lineSum += scanDirectory(subdir, spaces+1, subdirname); 1.67 + } 1.68 + closedir(subdir); 1.69 + continue; 1.70 + } 1.71 + 1.72 + // Count lines 1.73 + lines = 0; 1.74 + char filename[(1+strlen(currdir)+strlen(entry->d_name))]; 1.75 + strcpy(filename, currdir); 1.76 + strcat(filename, "/"); 1.77 + strcat(filename, entry->d_name); 1.78 + if (testSuffix(filename)) 1.79 + { 1.80 + FILE *file = fopen(filename, "r"); 1.81 + if (file == NULL) 1.82 + { 1.83 + perror(" File acces failed"); 1.84 + continue; 1.85 + } 1.86 + 1.87 + do 1.88 + { 1.89 + a = fgetc(file); 1.90 + 1.91 + if (a == 10) 1.92 + { 1.93 + lines++; 1.94 + } 1.95 + } while (a != EOF); 1.96 + fclose(file); 1.97 + 1.98 + // Print line count 1.99 + printf("%14d lines\n", lines); 1.100 + 1.101 + lineSum += lines; 1.102 + } 1.103 + else 1.104 + { 1.105 + // Print hint 1.106 + printf("%20s\n", "no match"); 1.107 + } 1.108 + } 1.109 + } 1.110 + return lineSum; 1.111 +} 1.112 + 1.113 +int main(int argc, char** argv) 1.114 +{ 1.115 + // Help text 1.116 + const char* helpText = 1.117 + "\nUsage:\n%s [-h|--help|(-s=<suffix>|-S=<suffix>)|(-r|-R)|<directory>]" 1.118 + "\n\nCounts the line terminator characters (\\n) within all" 1.119 + " files in the specified\ndirectory." 1.120 + "\n\nOptions:" 1.121 + "\n -h, --help - this help text" 1.122 + "\n -s=<suffixes> - only count files with these suffixes (separated" 1.123 + "\n by commas)" 1.124 + "\n -S=<suffixes> - count any file except those with these suffixes" 1.125 + "\n (separated by commas)" 1.126 + "\n -R - excludes subdirectories" 1.127 + "\n -r - includes subdirecotires" 1.128 + "\n\n" 1.129 + "The default call without any options is:" 1.130 + "\n %s -r ./ -S=\n" 1.131 + "That means each file in each subdirectory is counted. If you want to count" 1.132 + "\nC source code in your working directory and its subdirectories, type:" 1.133 + "\n %s -s=.c\n"; 1.134 + 1.135 + // Program name 1.136 + char* prgName = strrchr(argv[0], '/'); 1.137 + if (prgName == NULL) 1.138 + { 1.139 + prgName = argv[0]; 1.140 + } 1.141 + else 1.142 + { 1.143 + prgName++; 1.144 + } 1.145 + 1.146 + // Defaults 1.147 + char* _suffix = ""; 1.148 + char* _directory = "./"; 1.149 + 1.150 + // Get arguments 1.151 + char* directory; 1.152 + char* suffix; 1.153 + bool showHelp = false; 1.154 + recursive = true; 1.155 + includeSuffixes = false; 1.156 + char checked = 0; 1.157 + 1.158 + for (int t = 1 ; t < argc ; t++) 1.159 + { 1.160 + if (strncmp(argv[t], "-s=", 3) == 0) 1.161 + { 1.162 + if ((checked & 1) > 0) 1.163 + { 1.164 + printf(helpText, prgName, prgName, prgName); 1.165 + return -1; 1.166 + } 1.167 + includeSuffixes = true; 1.168 + suffix = argv[t]+3; 1.169 + checked |= 1; 1.170 + } 1.171 + else if (strncmp(argv[t], "-S=", 3) == 0) 1.172 + { 1.173 + if ((checked & 1) > 0) 1.174 + { 1.175 + printf(helpText, prgName, prgName, prgName); 1.176 + return -1; 1.177 + } 1.178 + includeSuffixes = false; 1.179 + suffix = argv[t]+3; 1.180 + checked |= 1; 1.181 + } 1.182 + else if (strcmp(argv[t], "-h") == 0 || strcmp(argv[t], "--help") == 0) 1.183 + { 1.184 + if ((checked & 2) > 0) 1.185 + { 1.186 + printf(helpText, prgName, prgName, prgName); 1.187 + return -1; 1.188 + } 1.189 + checked |= 2; 1.190 + showHelp = true; 1.191 + } 1.192 + else if (strcmp(argv[t], "-r") == 0) 1.193 + { 1.194 + if ((checked & 4) > 0) 1.195 + { 1.196 + printf(helpText, prgName, prgName, prgName); 1.197 + return -1; 1.198 + } 1.199 + checked |= 4; 1.200 + recursive = true; 1.201 + } 1.202 + else if (strcmp(argv[t], "-R") == 0) 1.203 + { 1.204 + if ((checked & 4) > 0) 1.205 + { 1.206 + printf(helpText, prgName, prgName, prgName); 1.207 + return -1; 1.208 + } 1.209 + checked |= 4; 1.210 + recursive = false; 1.211 + } 1.212 + else 1.213 + { 1.214 + if ((checked & 8) > 0) 1.215 + { 1.216 + printf(helpText, prgName, prgName, prgName); 1.217 + return -1; 1.218 + } 1.219 + checked |= 8; 1.220 + directory = argv[t]; 1.221 + } 1.222 + } 1.223 + 1.224 + // Show help and quit 1.225 + if (showHelp) 1.226 + { 1.227 + printf(helpText, prgName, prgName, prgName); 1.228 + return 0; 1.229 + } 1.230 + 1.231 + // Default values 1.232 + if ((checked & 1) == 0) 1.233 + { 1.234 + suffix = _suffix; 1.235 + } 1.236 + 1.237 + if ((checked & 8) == 0) 1.238 + { 1.239 + directory = _directory; 1.240 + } 1.241 + 1.242 + // Find tokens 1.243 + char* finder; 1.244 + suffixc = 1; 1.245 + finder = strchr(suffix, ','); 1.246 + while (finder != NULL) 1.247 + { 1.248 + suffixc++; 1.249 + finder = strchr(finder+1, ','); 1.250 + } 1.251 + suffixv = (char**) malloc(sizeof(suffixv)*suffixc); 1.252 + if (suffixv == NULL) 1.253 + { 1.254 + fprintf(stderr, "Memory allocation failed.\n"); 1.255 + return 1; 1.256 + } 1.257 + finder = strtok(suffix, ","); 1.258 + int c = 0; 1.259 + while (finder != NULL) 1.260 + { 1.261 + suffixv[c] = finder; 1.262 + c++; 1.263 + finder = strtok(NULL, ","); 1.264 + } 1.265 + 1.266 + // Open directory 1.267 + DIR *dir = opendir(directory); 1.268 + if (dir == NULL) 1.269 + { 1.270 + perror("Operation failed"); 1.271 + free(suffixv); 1.272 + return 1; 1.273 + } 1.274 + 1.275 + // Scan directory 1.276 + int lines = scanDirectory(dir, 0, directory); 1.277 + 1.278 + // Print double line and line count 1.279 + for (int t = 0 ; t < 80 ; t++) 1.280 + { 1.281 + printf("="); 1.282 + } 1.283 + printf("\n%74d lines\n", lines); 1.284 + 1.285 + closedir(dir); 1.286 + free(suffixv); 1.287 + return 0; 1.288 +}