Return to main.cpp CVS log | Up to [Pegasus] / pegasus_unsupported / utils / chlicense |
File: [Pegasus] / pegasus_unsupported / utils / chlicense / main.cpp
(download)
Revision: 1.5, Mon Apr 30 18:02:14 2007 UTC (17 years, 1 month ago) by mike Branch: MAIN CVS Tags: HEAD Changes since 1.4: +17 -0 lines BUG#: 99999 TITLE: chlicense DESCRIPTION: Added logic for handling WSM licenses. |
//%2006//////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation, The Open Group. // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; Symantec Corporation; The Open Group. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //%///////////////////////////////////////////////////////////////////////////// #include <sys/types.h> #include <regex.h> #include <sys/stat.h> #include <unistd.h> #include <cstring> #include <cstdarg> #include <string> #include <vector> #include <cctype> #include <fstream> #include <cstdio> #include <dirent.h> #include <fstream> using namespace std; static const char* arg0; //============================================================================== // // options: // //============================================================================== bool opt_help = false; bool opt_verbose = false; //============================================================================== // // regular expressions: // //============================================================================== static const char* start[] = { "^//%[0-9][0-9][0-9][0-9].*", "^#//%[0-9][0-9][0-9][0-9].*", "^//%{.*", "^##%{.*", #ifdef WSM "^\\*\\*====.*$", "^##====.*", #endif (char*)0, }; static size_t start_size = sizeof(start) / sizeof(start[0]); regex_t start_rx[sizeof(start) / sizeof(start[0])]; static const char* body[] = { "^//.*", "^#//.*", "^##.*", #ifdef WSM "^\\*\\*.*", "^##.*", #endif (char*)0, }; static size_t body_size = sizeof(body) / sizeof(body[0]); regex_t body_rx[sizeof(body) / sizeof(body[0])]; static const char* end[] = { "^//%.*", "^#//====.*", "^//%}.*", "^##%}.*", #ifdef WSM "^\\*\\*====.*$", "^##====.*", #endif (char*)0, }; static size_t end_size = sizeof(end) / sizeof(end[0]); regex_t end_rx[sizeof(end) / sizeof(end[0])]; //============================================================================== // // match() // //============================================================================== bool match(const char* text[], regex_t rx[], const char* str) { for (size_t i = 0; text[i]; i++) { if (regexec(&rx[i], str, 0, NULL, 0) == 0) return true; } return false; } //============================================================================== // // err() // //============================================================================== void err(const char* format, ...) { fputc('\n', stderr); va_list ap; fprintf(stderr, "%s: ", arg0); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); fputc('\n', stderr); fputc('\n', stderr); exit(1); } //============================================================================== // // warn() // //============================================================================== void warn(const char* format, ...) { va_list ap; fprintf(stderr, "%s: warning: ", arg0); va_start(ap, format); vfprintf(stderr, format, ap); fputc('\n', stderr); va_end(ap); } //============================================================================== // // get_opt() // //============================================================================== static char *opt_arg = NULL; static int opt_ind = 1; static int opt_err = 1; static int opt_opt; static int get_opt(int argc, char** argv, const char* optstring) { for (int i = opt_ind; i < argc; i++) { char* arg = argv[i]; if (arg[0] == '-' && arg[1] != '\0') { int opt = arg[1]; const char* p = strchr(optstring, opt); opt_arg = NULL; if (p == NULL) { if (opt_err) fprintf(stderr, "%s: invalid option -- %c\n", argv[0], opt); opt_opt = opt; opt = '?'; } else if (p[1] == ':') { if ((opt_arg = argv[i+1]) == NULL) { if (opt_err) { fprintf(stderr, "%s: option requires an argument -- %c\n", argv[0], opt); } opt_opt = opt; if (*optstring == ':') opt = ':'; else opt = '?'; } } int n = opt_arg ? 2 : 1; memmove( argv + opt_ind + n, argv + opt_ind, (i - opt_ind) * sizeof(char*)); argv[opt_ind++] = arg; if (opt_arg) argv[opt_ind++] = opt_arg; return opt; } } return -1; } //============================================================================== // // help() // //============================================================================== const char USAGE[] = "\ \n\ Usage: %s [options] license\n\ \n\ Description:\n\ This utility attempts to replace the license text in all files\n\ in or below the current directory. The range of lines comprising\n\ the exiting license have the following form:\n\ \n\ 1 start-line\n\ 0 or more more body-lines\n\ 1 end-line\n\ \n\ A start-line matches ONE of these regular expressions:\n\ \n\ ^//%[0-9][0-9][0-9][0-9].*\n\ ^#//%[0-9][0-9][0-9][0-9].*\n\ ^//%{.*\n\ ^##%{.*\n\ \n\ A body-line matches ONE of these regular expressions:\n\ \n\ ^//.*\n\ ^#//.*\n\ ^##.*\n\ \n\ An end-line matches ONE of these regular expressions:\n\ \n\ ^//%.*\n\ ^#//%.*\n\ ^//%}.*\n\ ^##%}.*\n\ \n\ If the end-line is missing, then the last body-line is used\n\ as the end-line.\n\ \n\ The replacement license must NOT contain any comment delimiters.\n\ Delimiters are added by this utility.\n\ \n\ Options:\n\ -h print this help message.\n\ -v verbose\n\ \n"; void help() { printf(USAGE, arg0); exit(0); } //============================================================================== // // has_extension() // //============================================================================== bool has_extension(const string& path, const string& ext) { size_t pos = path.find(ext); if (pos == string::npos) return false; return pos + ext.size() == path.size(); } //============================================================================== // // is_text_file() // //============================================================================== bool is_text_file(const string& path) { // These may contain special characters in rare cases. if (has_extension(path, ".c") || has_extension(path, ".cpp") || has_extension(path, ".h") || has_extension(path, ".hpp")) { return true; } ifstream is(path.c_str()); if (!is) return false; char c; while (is.get(c)) { if (c < 0) return false; } return true; } //============================================================================== // // load() // //============================================================================== void load(const string& path, vector<string>& lines) { ifstream is(path.c_str()); if (!is) err("failed to open %s", path.c_str()); string line; while (getline(is, line)) lines.push_back(line); } //============================================================================== // // process() // //============================================================================== void process(const string& path, const vector<string>& license) { if (opt_verbose) printf("%s\n", path.c_str()); vector<string>lines; load(path, lines); size_t start_line = size_t(-1); size_t end_line = size_t(-1); // Find line range of license: for (size_t i = 0; i < lines.size(); i++) { string line = lines[i]; if (start_line == size_t(-1)) { if (match(start, start_rx, line.c_str())) start_line = i; } else if (match(end, end_rx, line.c_str())) { end_line = i; break; } else if (!match(body, body_rx, line.c_str())) { end_line = i - 1; break; } } if (start_line == size_t(-1)) { if (has_extension(path, ".c") || has_extension(path, ".cpp") || has_extension(path, ".h") || has_extension(path, ".hpp") || path == "Makefile") { warn("%s: start-line not found", path.c_str()); } } else { if (end_line == size_t(-1)) end_line = lines.size() - 1; // Open output file. ofstream os(path.c_str()); if (!os) err("failed to open %s", path.c_str()); // Write lines up to start-line. for (size_t i = 0; i < start_line; i++) os << lines[i] << endl; // Get comment-character. char ch = lines[start_line][0]; #ifdef WSM if (ch == '*') ch = '/'; #endif // Write start-line. os << ch << ch << '%' << '{'; for (size_t i = 0; i < 76; i++) os << ch; os << endl; // Write license lines. for (size_t i = 0; i < license.size(); i++) { if (license[i].size()) os << ch << ch << ' ' << license[i] << endl; else os << ch << ch << endl; } // Write end-line. os << ch << ch << '%' << '}'; for (size_t i = 0; i < 76; i++) os << ch; os << endl; // Write lines after end-line. for (size_t i = end_line + 1; i < lines.size(); i++) os << lines[i] << endl; } } //============================================================================== // // chlicense() // //============================================================================== void chlicense(const string& root, const vector<string>& license) { // Open directory. DIR* dir = opendir(root.c_str()); if (!dir) err("opendir() failed: %s", root.c_str()); // Iterate directory files. dirent* ent; vector<string> directories; while ((ent = readdir(dir)) != NULL) { // Skip current and parent directories. string name = ent->d_name; if (name == "." || name == "..") continue; // Skip CVS directories. if (name == "CVS") continue; // Save and skip directories. string path = root + string("/") + name; struct stat st; if (stat(path.c_str(), &st) != 0) err("failed to stat %s", path.c_str()); if (S_ISDIR(st.st_mode)) { directories.push_back(path); continue; } // Skip non-text files. if (!is_text_file(path)) continue; // Process file. process(path, license); } closedir(dir); // Recurse into directories. for (size_t i = 0; i < directories.size(); i++) chlicense(directories[i], license); } //============================================================================== // // compile() // //============================================================================== void compile(const char* text[], regex_t rx[]) { for (size_t i = 0; text[i]; i++) { if (regcomp(&rx[i], text[i], REG_NOSUB) != 0) err("failed to compile regular expression: %s",text[i]); } } //============================================================================== // // main() // //============================================================================== int main(int argc, char** argv) { arg0 = argv[0]; // Process options: int opt; while ((opt = get_opt(argc, argv, "hv")) != -1) { switch (opt) { case 'h': opt_help = true; break; case 'v': opt_verbose = true; break; case '?': case ':': help(); exit(1); default: err("unexpected"); } } argc -= opt_ind; argv += opt_ind; // Help! if (opt_help) help(); // Check arguments (we expect once) if (argc != 1) err("wrong number of arguments; try -h for help"); // Compile regular expressions. compile(start, start_rx); compile(body, body_rx); compile(end, end_rx); // Load license file. vector<string> license; load(argv[0], license); // Process files. chlicense(".", license); return 0; }
No CVS admin address has been configured |
Powered by ViewCVS 0.9.2 |