/**
*Some little program for finding and prettyprinting //TODO comments.
*
*License: the MIT-License also known as X11-License
*Copyright: (c) 2010 Marcel Fischer
*/
module todo;
import std.string : strip, chomp, find, ifind, format;
import std.stream : BufferedFile;
import std.stdio;
static import std.file;
static import std.path;
//I use string only for pseudo immutables for compa with D2
//private char[][string] todos;
private char[] todos="";
private char[] highPrioTodos="";
private int count = 0;
private char[] exts = "";
private string versionnum = "0.1";
debug private string versiontext= "BETA DEBUG";
else private string versiontext= "BETA";
/*
//Use std.path.sep instead
version(Windows) { private const string seperator = "\\";}
version(Linux) { private const string seperator = "/"; }
static assert(is(typeof(seperator)));
*/
alias std.path.sep seperator;
void main(string[] args) {
showInit();
standardExts();
debug writefln("StExts: %s", exts);
if(args.length <= 1) {
} else {
foreach(arg; args[1..$]) {
if(!std.file.exists(arg)) {
writefln("%s doesn't exist!",arg);
continue;
}
search(arg);
}
printResults();
}
}
void showInit() {
writefln("Todo written by Marcel Fischer");
writefln("Version %s %s\n", versionnum, versiontext);
}
void standardExts() {
exts ~= "{d}{di}{c}{cpp}{h}{hpp}{cxx}{py}{rb}{pl}{php}{php5}{cs}{java}{tex}";
}
void showHelp() {
//TODO write showHelp() ;-)
}
void search(string path) {
//The path has to exist
assert(std.file.exists(path));
debug writef("\nSearching in %s...",path);
//When it's a directory
if(std.file.isdir(path)) {
debug writefln(" it's directory");
//recursively seach in subdirectorys
auto entrys = std.file.listdir(path);
foreach(entry; entrys) {
if(entry != "." && entry != "..")
search(path ~ seperator ~ entry);
}
//when it's a file
} else if (std.file.isfile(path)){
debug writefln(" it's file");
//if file is not a programming file
if(! find(exts, format("{%s}", std.path.getExt(path)) ) >= 0) {
debug writef("ignore: %s", format("{%s}", std.path.getExt(path)));
return;
}
BufferedFile file = new BufferedFile(path);
scope(exit) file.close();
char[] line = ""; //the current line
int linenum = 0; //linenumber
bool highPrio = false; //if high priority
while(!file.eof()) {
line = file.readLine();
linenum++;
debug writef(" %s ",linenum);
highPrio = false;
int index = ifind(line, "//TODO");
if(index >= 0) {
//Take the line after todo
line = line[index+("//TODO".length)..$];
line = strip(chomp(line));
if(line[0] == "$"[0]) {
highPrio = true;
line = line[1..$];
}
if(!highPrio)
todos ~= createMessage(path,linenum,line);
else
highPrioTodos ~= createMessage(path,linenum,line);
count++;
}
}
} else {
assert(0); //File can't be neither a directory nor a file
}
}
string createMessage(string path, int linenum, string message) {
return format(" * %15s(%s): %s\n", std.path.getBaseName(path),
linenum, message);
}
void printResults() {
writefln("%s Results found\n",count);
if(highPrioTodos.length > 0)
writefln("Todos with high priority:\n%s\n",highPrioTodos);
if(todos.length > 0)
writefln("%sodos:\n%s\n", highPrioTodos.length > 0 ? "Other t" : "T", todos);
if(highPrioTodos.length == 0 && todos.length == 0)
writefln("Whoa, nothing left to do!");
}