/* * aegis - project change supervisor * Copyright (C) 1998, 2000-2003, 2005-2008 Peter Miller * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see * . */ auto script_name; script_name = getenv("SCRIPT_NAME"); if (script_name == "") script_name = "http://localhost/cgi-bin/aegis.cgi"; auto pn, p; pn = project_name(); p = project[pn]; auto legend_used; legend_used = { }; columns({width = 1000; }); print("Content-Type: text/html"); print(""); print(""); print(""); print(""); print(""); print(""); print(""); /* * Netscape 4.x has numerous CSS bugs, two of which need mentioning. * 1. If a style sheet is not present Netscape says 404 Not found, when * it should silently ignore it. 2. Style sheets who's media is not * "screen" will be ignored. Fortunately we can use (2) to get around (1). */ print(""); auto stack, depth, n; depth=0; stack[depth] = project[pn].state.name; while ("" != ( n = project[stack[depth]].state.parent_name )) { stack[++depth] = n; } while ( depth >= 0) { print(""); } print(""); auto cause_map; cause_map = { chain = "255+0+0"; internal_bug = "255+255+0"; external_bug = "192+192+0"; internal_enhancement = "0+255+0"; external_enhancement = "0+192+0"; internal_improvement = "0+255+255"; external_improvement = "0+192+192"; }; auto size_map; size_map = { create = 12; modify = 16; remove = 8; }; /* * use the file prefix named on the command line * or the top level if not specified */ auto prefix; if (count(arg) == 0) prefix = ""; else prefix = arg[0] ## "/"; print("Project " ## quote_html(pn) ## " Change Density by File" ## (prefix == "" ? "" : (", Directory " ## quote_html(prefix)))); print("

"); auto href; print("Project"); auto long_project_name; auto prj_name_parts; prj_name_parts = split(pn, '.'); href = script_name ## "?file@proj_menu+project@" ## quote_url(prj_name_parts[0]); long_project_name = "" ## quote_html(prj_name_parts[0]) ## ""; auto j; for (j=1; j" ## quote_html(prj_name_parts[j]) ## ""; }; long_project_name = "“" ## long_project_name ## "”,
"; /* HTTP limits lines to 510 characters */ for (j in wrap(long_project_name, 510)) print(j); auto long_dir_name, dir_parts; if (prefix != "") { href = script_name ## "?file@file_densi+project@" ## quote_url(pn); print("Change Density by File
"); long_dir_name = "Directory “"; href ##= "+"; dir_parts = split(prefix, '/'); for (j = 0; j < count(dir_parts) - 1; j++) { href ##= dir_parts[j]; long_dir_name ##= "" ## quote_html(dir_parts[j]) ## "/"; href ##= "/"; }; long_dir_name ##= quote_html(dir_parts[count(dir_parts) - 1]) ## "”"; /* HTTP limits lines to 510 characters */ for (j in wrap(long_dir_name, 510)) print(j); } else print("Change Density by File"); print("

"); print("
"); auto ps; ps = project[project_name()].state; /* * This will hold the cumulative statistics * history[filename].is_a_directory * history[filename].count[cause][action] */ auto remember; remember = {}; /* * scan the project files for context */ auto ph, cs, cf, max, filename, is_a_directory; for (cf in ps.src) { if (cf.usage == build) continue; filename = cf.file_name; if (prefix != "") { if (substr(filename, 0, length(prefix)) != prefix) continue; filename = substr(filename, length(prefix), 99999); } filename = split(filename, "/"); is_a_directory = (count(filename) > 1); filename = filename[0]; if (typeof(remember[filename]) == "nul") remember[filename] = { count = {}; total = 0; }; if (is_a_directory) remember[filename].is_a_directory = true; } /* * scan all completed changes * for any of the named files */ max = 1; for (ph in ps.branch.history) { cs = ps.branch.change[ph.change_number]; for (cf in cs.src) { if (cf.usage == build && cf.action == modify) continue; filename = cf.file_name; if (prefix != "") { if (substr(filename, 0, length(prefix)) != prefix) continue; filename = substr(filename, length(prefix), 99999); } filename = split(filename, "/"); is_a_directory = (count(filename) > 1); filename = filename[0]; if (typeof(remember[filename]) == "nul") remember[filename] = { count = {}; total = 0; }; if (is_a_directory) remember[filename].is_a_directory = true; if (typeof(remember[filename].count[cs.cause]) == "nul") remember[filename].count[cs.cause] = { total = 0; }; remember[filename].count[cs.cause].total++; remember[filename].count[cs.cause][cf.action]++; remember[filename].total++; if (remember[filename].total > max) max = remember[filename].total; legend_used[cs.cause] = true; } } /* * print the accumulated history */ max = 300.0 / max; auto cause, action; auto width, height, clr; print(""); for (filename in sort(keys(remember))) { cf = remember[filename]; if (cf.is_a_directory) href = "densi"; else href = "menu"; href = script_name ## "?file@file_" ## href ## "+" ## quote_url(prefix ## filename) ## "+project@" ## quote_url(project_name()); print(""); } print("
"); print(""); print("" ## quote_html(filename) ## "" ## (cf.is_a_directory ? "/" : "")); print(""); print(cf.total); print(""); for (cause in [chain, internal_bug, internal_enhancement, internal_improvement, external_bug, external_enhancement, external_improvement]) { for (action in [create, modify, remove]) { clr = cause_map[cause]; if (clr == "") clr = "191+191+191"; if (typeof(cf.count[cause]) == "nul") cf.count[cause] = {}; width = cf.count[cause][action]; if (width <= 0) continue; width = round(width * max); if (width < 3) width = 3; height = size_map[action]; if (height < 3) height = 3; href = script_name ## "?file@rect+" ## width ## "+" ## height ## "+color+" ## clr; print(""); } } print("
"); print("
"); print("
"); print("
"); print("

Legend

"); print(""); print(""); for (cause in [chain, internal_bug, internal_enhancement, internal_improvement, external_bug, external_enhancement, external_improvement]) { if (!legend_used[cause]) continue; print(""); clr = cause_map[cause]; width = 30; for (action in [create, modify, remove]) { print(""); } print(""); } print("
CreateModifyRemoveCause
"); height = size_map[action]; href = script_name ## "?file@rect+" ## width ## "+" ## height ## "+color+" ## clr; print(""); print(""); print(cause); print("
"); print("
"); print("
"); print("

["); print("Project List"); print("|"); href = script_name ## "?file@proj_menu+project@" ## quote_url(pn); print("Project Menu"); print("|"); href = script_name ## "?file@chan_list+project@" ## quote_url(pn); print("Change List"); print("]

"); print("
"); print("This page was generated " ## now() ## "."); print("");