/* $Id: wsPage.cpp,v 1.3 2001/08/06 00:25:08 mike Exp $ *********************************************************************** * libwsmake - Core functionality library of wsmake * * Copyright (C) 1999,2000,2001 Michael Brownlow * * * * 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 2 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, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * * For questions and comments, please email the author at: * * mike@wsmake.org * ***********************************************************************/ #include #include #include "wsPage.h" #include "wsUtil.h" #include "wsmake.h" using namespace std; wsPage::wsPage(string config_dir) : sync_printed(0) { setConfigDir(config_dir); setSourcePage(""); setOutputPage(""); setSourceDir(""); setOutputDir(""); } void wsPage::copyTo(wsPage *copy) { copy->setName(name); copy->setSourceDir(this->getSourceDir()); copy->setOutputDir(this->getOutputDir()); copy->setConfigDir(config_dir); copy->setSourcePage(this->getSourcePage()); copy->setOutputPage(this->getOutputPage()); } int wsPage::dump(ofstream *output) { *output << "dump: " << output_page << endl; return 1; } string wsPage::getFullOutputPage(void) const { string val; val.assign(collapsePath((this->getFullOutputDir() + "/" + this->getOutputPage()).c_str(), NULL)); return val; } string wsPage::getFullOutputPageDir(void) const { string val; val.assign(collapsePath((this->getFullOutputDir() + "/" + this->getOutputPageDir()).c_str(), NULL)); return val; } string wsPage::getFullSourcePage(void) const { string val; val.assign(collapsePath((this->getFullSourceDir() + "/" + this->getSourcePage()).c_str(), NULL)); return val; } string wsPage::getFullSourcePageDir(void) const { string val; val.assign(collapsePath((this->getFullSourceDir() + "/" + this->getSourcePageDir()).c_str(), NULL)); return val; } string wsPage::getFullOutputDir(void) const { string val; if(output_dir[0] == '/') { return output_dir; } else { val.assign(collapsePath((config_dir + "/" + output_dir).c_str(), NULL)); return val; } } string wsPage::getFullSourceDir(void) const { string val; if(source_dir[0] == '/') { return source_dir; } else { val.assign(collapsePath((config_dir + "/" + source_dir).c_str(), NULL)); return val; } } string wsPage::getOutputPageDir(void) const { string dir = output_page; unsigned x = dir.rfind("/"); if(x < string::npos) { // Not originally "testing.html" dir.erase(x); if(dir.length() == 0) { // If originally "/testing.html" return "."; } else { return dir; // If originally "/blah/testing.html" // or "blah/testing.html" } } else { return "."; } } string wsPage::getSourcePageDir(void) const { string dir = source_page; unsigned x = dir.rfind("/"); if(x < string::npos) { // Not originally "testing.html" dir.erase(x); if(dir.length() == 0) { // If originally "/testing.html" return "."; } else { return dir; // If originally "/blah/testing.html" // or "blah/testing.html" } } else { return "."; } } void wsPage::setConfigDir(string config_dir) { this->config_dir.assign(collapsePath(config_dir.c_str(), NULL)); } void wsPage::setName(string name) { this->name.assign(name); } void wsPage::setOutputDir(const string output_dir) { this->output_dir.assign(collapsePath(output_dir.c_str(), NULL)); } void wsPage::setOutputPage(string output_page) { this->output_page.assign(collapsePath(output_page.c_str(), NULL)); } void wsPage::setSourceDir(string source_dir) { this->source_dir.assign(collapsePath(source_dir.c_str(), NULL)); } void wsPage::setSourcePage(string source_page) { this->source_page.assign(collapsePath(source_page.c_str(), NULL)); } int wsPage::clean(void) { __wsmake_print(1,"cleaning: `%s'...",output_page.c_str()); if(remove(getFullOutputPage().c_str()) != 0) { __wsmake_print(1,"failed (%d)!\n", errno); } else { __wsmake_print(1,"done.\n"); } return 1; } void wsPage::setLastModByFile() { this->setLastMod(getFileLastMod(this->getFullSourcePage())); } int wsPage::checkOutputDir() { DBGPRINT(("M: checking output directory `%s'\n", this->getFullOutputDir().c_str())); // Check if output_dir exists, if not create it int err; if(fileExists(this->getFullOutputDir().c_str())) { if(!fileIsDir(this->getFullOutputDir().c_str())) { __wsmake_print_error("Warning: Either I couldn't access the output " "directory, \n or it isn't a directory.\n"); } else { __wsmake_print(3," "); return this->checkOutputPageDir(); } } else { if((err=fileMkDir(this->getFullOutputDir(),0777)) != 0) { __wsmake_print(3,"D"); return this->checkOutputPageDir(); } else { __wsmake_print(1,"mkdir error: (%d) %s, output `%s'\n", err, strerror(err), this->getFullOutputDir().c_str()); return 0; } } return 0; } int wsPage::checkOutputPageDir() { DBGPRINT(("M: checking output page directory `%s'\n", this->getFullOutputPageDir().c_str())); int err; if(this->getFullOutputPageDir() != "") { if(fileExists(this->getFullOutputPageDir().c_str())) { if(!fileIsDir(this->getFullOutputPageDir().c_str())) { __wsmake_print_error("Warning: Either I couldn't access the output " "page's directory, \n" " or it isn't a directory.\n"); } else { return 1; } } else { if((err=fileMkDir(this->getFullOutputPageDir(),0777)) != 0) { return 1; } else { __wsmake_print(1,"mkdir error: (%d) %s, output `%s'\n", err, strerror(err), this->getFullOutputDir().c_str()); return 0; } } return 0; } else { return 1; } } int wsPage::sourcePageExists(void) const { struct stat statbuf; int err; err = stat(this->getFullSourcePage().c_str(),&statbuf); if(err == -1) { if(errno == ENOENT) return 0; } return 1; } int wsPage::outputPageExists(void) const { struct stat statbuf; int err; err = stat(this->getFullOutputPage().c_str(),&statbuf); if(err == -1) { if(errno == ENOENT) return 0; } return 1; } // Gets the last mod date of the given file and returns it time_t wsPage::getSourceLastMod(void) const { struct stat statbuf; int err; err = stat(this->getFullSourcePage().c_str(),&statbuf); if(!err) { return statbuf.st_mtime; } else { return -1; } } time_t wsPage::getOutputLastMod(void) const { struct stat statbuf; int err; err = stat(this->getFullOutputPage().c_str(),&statbuf); if(!err) { return statbuf.st_mtime; } else { return -1; } } void wsPage::setPermissions(void) { int error; if((error=applyStat(this->getFullSourcePage().c_str(), this->getFullOutputPage().c_str()))) { __wsmake_print(1,"(permission error (%s):\n%s\nto\n%s\n)", strerror(error), this->getFullSourcePage().c_str(), this->getFullOutputPage().c_str()); } } void wsPage::setTime(void) { int error; if((error=applyTime(this->getFullSourcePage().c_str(), this->getFullOutputPage().c_str()))) { __wsmake_print(1,"(permission error (%s):\n%s\nto\n%s\n)", strerror(error), this->getFullSourcePage().c_str(), this->getFullOutputPage().c_str()); } } int wsPage::getPageTagID(const string *tag) { if(strcmp(tag->c_str(), "name") == 0) return TAG_NAME; else if(strcmp(tag->c_str(), "web_path") == 0) return TAG_SOURCE_PAGE; else if(strcmp(tag->c_str(), "web_page") == 0) return TAG_SOURCE_PAGE; else if(strcmp(tag->c_str(), "source_page") == 0) return TAG_SOURCE_PAGE; else if(strcmp(tag->c_str(), "output_page") == 0) return TAG_OUTPUT_PAGE; else if(strcmp(tag->c_str(), "source_dir") == 0) return TAG_SOURCE_DIR; else if(strcmp(tag->c_str(), "output_dir") == 0) return TAG_OUTPUT_DIR; return UNKNOWN; } int wsPage::load(ifstream *config) { string buff; string tag; string value; int done = 0; int line = 0; while((!done) && (line=getNextConfigLine(config, &buff))!=0) { splitString(&tag, &value, &buff); if(tag.find("}") != string::npos) { done = 1; } else { switch(this->getPageTagID(&tag)) { case TAG_NAME : chopQuotes(&value); this->setName(value); break; case TAG_SOURCE_PAGE : chopQuotes(&value); this->setSourcePage(value); break; case TAG_OUTPUT_PAGE : chopQuotes(&value); this->setOutputPage(value); break; case TAG_SOURCE_DIR : chopQuotes(&value); this->setSourceDir(value); break; case TAG_OUTPUT_DIR : chopQuotes(&value); this->setOutputDir(value); break; case UNKNOWN : default : __wsmake_print_error("unknown page section skipped (line %d): %s\n", line, tag.c_str()); return 0; break; } } } this->setLastModByFile(); if(source_page.length() == 0) { __wsmake_print_error("The web_page or source_page attribute must " "be defined.\n"); } if(output_page.length() == 0) { this->setOutputPage(source_page); } return 1; } int wsPage::sync(int force) { sync_printed = 0; if(force) __wsmake_print(2,"Forcing page `%s'\n", output_page.c_str()); return 1; } int wsPage::nameBegins(const string *name) const { // The STL defines: // int compare(size_type pos, size_type n, const basic_string& s) const // // But libstdc++ < 3.0 bastring.h is: // int compare(const basic_string& s, size_type pos, size_type n) const // // COMPARE_ARGS_SWAPPED is set by configure // // Since newer versions of wsmake are targeted only for gcc 3.0, all // of this will probably go away eventually. #ifdef COMPARE_ARGS_SWAPPED if(this->name.compare(*name, 0, name->size()) == 0) #else if(this->name.compare(0, name->size(), *name) == 0) #endif return 1; return 0; } int wsPage::nameEnds(const string *name) const { // See nameBegins for discussion on compare method #ifdef COMPARE_ARGS_SWAPPED if(this->name.compare(*name, (this->name.size() - name->size()), name->size()) == 0) #else if(this->name.compare(this->name.size() - name->size(), name->size(), *name) == 0) #endif return 1; return 0; } int wsPage::nameHas(const string *name) const { if(this->name.find(*name) != string::npos) return 1; return 0; } void wsPage::print(void) const { __wsmake_print(3," Source Page : %s\n", source_page.c_str()); __wsmake_print(3," Output Page : %s\n", output_page.c_str()); __wsmake_print(3," Source Directory: %s\n", source_dir.c_str()); __wsmake_print(3," Output Directory: %s\n", output_dir.c_str()); } void wsPage::printWebPath(void) const { __wsmake_print("%s", output_page.c_str()); } void wsPage::printSync(void) { if(!sync_printed) { __wsmake_print(1,"P: --- %s\n", output_page.c_str()); sync_printed = 1; } }