/* $Id: wsPagePart.cpp,v 1.5 2001/09/04 01:11:40 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 "wsmake.h" #ifdef HAVE_GLOB_H #include #endif #include "wsPagePart.h" #include "wsSubTag.h" #include "wsUtil.h" using namespace std; wsPagePart::wsPagePart (string config_dir, ifstream *config, wsPageGroup *pagegroup) : wsWebPage("",pagegroup) { this->setConfigDir(config_dir); this->load(config); if(!this->getPageGroup()->usingSourceTimestamp()) { this->setDatabaseKey(getDatabaseKey().c_str()); this->setValueType(DBA_DT_LONG); } DBGPRINT(("O:created: wsPagePart\n")); } wsPagePart::~wsPagePart(void) { DBGPRINT(("O:destroyed: wsPagePart\n")); } int wsPagePart::getPagePartTagID(const string *tag) { if(strcmp(tag->c_str(),"name") == 0) return TAG_NAME; else if(strcmp(tag->c_str(),"filename") == 0) return TAG_FILENAME; else if(strcmp(tag->c_str(),"directory") == 0) return TAG_DIRECTORY; else if(strcmp(tag->c_str(),"SubTag") == 0) return TAG_SUBTAG; else if(strcmp(tag->c_str(),"subtaggroup") == 0) return TAG_SUBTAGGROUP; else if(strcmp(tag->c_str(),"pageorder") == 0) return TAG_PAGEORDER; else if(strcmp(tag->c_str(),"theme") == 0) return TAG_THEME; else if(strcmp(tag->c_str(),"parse") == 0) return TAG_PARSE; else if(strcmp(tag->c_str(),"depend") == 0) return TAG_DEPEND; return UNKNOWN; } int wsPagePart::load(ifstream *config) { string buff; string tag; string value; int done = 0; int line = 0; #ifdef HAVE_GLOB_H int err; unsigned i; static glob_t matches; #endif // Set default for directory this->setDirectory(this->getPageGroup()->getPartDir()); while((!done) && (line=getNextConfigLine(config, &buff))!=0) { splitString(&tag, &value, &buff); if(tag.find("}") != string::npos) { done = 1; } else { switch(this->getPagePartTagID(&tag)) { case TAG_NAME : chopQuotes(&value); this->setName(value); break; case TAG_FILENAME : chopQuotes(&value); this->setFilename(value); break; case TAG_DIRECTORY : chopQuotes(&value); this->setDirectory(value); break; case TAG_SUBTAG : if(!this->getSubTagList()->pushBackSubTag(&value)) { __wsmake_print_error("Error adding subtag `%s' (line %d)\n", value.c_str(),line); } break; case TAG_SUBTAGGROUP : chopQuotes(&value); if(!this->getSubTagGroupList()->pushBackSubTagGroup (this->getPageGroup()->findSubTagGroupWithName(value))) { __wsmake_print_error("Error adding subtaggroup `%s' (line %d)\n", value.c_str(),line); } break; case TAG_PAGEORDER : chopQuotes(&value); if(!this->getPageOrderList()->pushBackPageOrder (this->getPageGroup()->findPageOrderWithName(value))) { __wsmake_print_error("Error adding pageorder `%s' (line %d)\n", value.c_str(),line); } break; case TAG_THEME : chopQuotes(&value); if(!this->getThemeList()->pushBackTheme (this->getPageGroup()->findThemeWithName(value))) { __wsmake_print_error("Error adding theme `%s' (line %d)\n", value.c_str(),line); } break; case TAG_DEPEND : chopQuotes(&value); if(value[0] != '/') { value.insert(0,"/"); value.insert(0, this->getFullSourcePageDir()); } #ifdef HAVE_GLOB_H if((err=glob(value.c_str(), GLOB_NOCHECK, NULL, &matches)) == 0) { for(i=0; i<(unsigned)matches.gl_pathc; i++) { value.assign(matches.gl_pathv[i]); if(!this->getDependList()->pushBackDepend (wsDepend::findOrCreate(this->getFullSourcePageDir(), value, this->getPageGroup()))) { __wsmake_print_error("Error adding depend `%s' (line %d)\n", value.c_str(),line); } } } else { __wsmake_print_error("error with glob: %d (line %d)\n", err, line); } #endif break; case TAG_PARSE : chopQuotes(&value); this->setParseType(value); break; case UNKNOWN : default : __wsmake_print_error("unknown pagepart tag skipped (line %d): %s\n", line,tag.c_str()); return 0; break; } } } return 1; } int wsPagePart::sync(int force) { long lastmod; bool using_timestamp = this->getPageGroup()->usingSourceTimestamp(); this->setSyncPrinted(0); if(using_timestamp || ready()) { DBGPRINT(("syncing wsPagePart `%s'\n", this->getOutputPage().c_str())); if(!using_timestamp) { // Sync nested objects first (non-referenced attributes) this->getSubTagList()->sync(force); this->getDependList()->sync(force); } // Does the source page exist? if(!sourcePageExists()) { DBGPRINT(("S: discard `%s' (no source page)\n", this->getOutputPage().c_str())); this->setStat(STATTYPE_NOSOURCEPAGE); return 0; } // Did they say to force an update? if(force) { DBGPRINT(("S: update `%s' (forced)\n", this->getOutputPage().c_str())); this->setStat(STATTYPE_FORCE); return 1; } if(!using_timestamp) { // Check if page is in database if(!this->dbKeyExists(this->getDatabaseKey().c_str())) { DBGPRINT(("S: update `%s' (no key)\n", this->getOutputPage().c_str())); this->setDatabaseKey(this->getDatabaseKey().c_str()); this->setDatabaseValue(this->getSourceLastMod()); this->setUpdate(true); this->setStat(STATTYPE_NEWPAGE); return 1; } // Get lastmod now that we know a record exists for this page if(this->getDatabaseValue(&lastmod)==NULL) { __wsmake_print_error("key value could not be found! (`%s')\n", this->getOutputPage().c_str()); return 0; } // Is the source file modified? if(lastmod < this->getSourceLastMod()) { DBGPRINT(("S: update `%s' (source file updated)\n", this->getOutputPage().c_str())); this->setStat(STATTYPE_SOURCEUPDATED); this->setUpdate(true); return 1; } // Were any subtags updated? if(this->subTagListIsUpdated()) { DBGPRINT(("S: update `%s' (subtag updated)\n", this->getOutputPage().c_str())); this->setStat(STATTYPE_SUBTAGUPDATED); this->setUpdate(true); return 1; } // Were any pageorders updated? if(this->pageOrderListIsUpdated()) { DBGPRINT(("S: update `%s' (output page is old)\n", this->getOutputPage().c_str())); this->setStat(STATTYPE_PAGEORDERUPDATED); this->setUpdate(true); return 1; } // Were any subtaggroups updated? if(this->subTagGroupListIsUpdated()) { DBGPRINT(("S: update `%s' (subtaggroup updated)\n", this->getOutputPage().c_str())); this->setStat(STATTYPE_SUBTAGGROUPUPDATED); this->setUpdate(true); return 1; } // Was a dependency updated? if(this->dependListIsUpdated()) { DBGPRINT(("S: update (dependency updated)\n")); this->setStat(STATTYPE_DEPENDUPDATED); this->setUpdate(true); return 1; } } } else { __wsmake_print_error("database isn't ready\n"); this->setStat(STATTYPE_ERROR); this->setUpdate(false); return 0; } return 0; } int wsPagePart::make(ofstream *out) { wsPageList *make_prepend_list = new wsPageList(); wsPageList *make_append_list = new wsPageList(); if(!this->setPageList(make_prepend_list, make_append_list)) return 0; if(!make_prepend_list->make(out)) return 0; this->parseContent(out); if(!make_append_list->make(out)) return 0; if(!this->getPageGroup()->usingSourceTimestamp()) { this->setDatabaseValue(getSourceLastMod()); } delete make_prepend_list; delete make_append_list; this->getDependList()->make(); return 1; } void wsPagePart::parseSubtags(string *line) { bool done = false; // FIXME: We should optimize first, add all tags to a new // list and do recursive replacement in place. Then we // simply parse each line with one pass while(!done) { if( ! ((this->getPageGroup()->parseSubtags(line) == 1) || (this->getSubTagList()->parse(line) == 1) || (this->getSubTagGroupList()->parse(line) == 1) || (this->getThemeList()->parse(line) == 1)) ) { done = true; } } } int wsPagePart::dump(ofstream *output) { *output << "dump: " << this->getOutputPage() << endl; return 1; } void wsPagePart::setFilename(const string filename) { this->filename.assign(filename); this->setOutputPage(filename); this->setSourcePage(filename); } void wsPagePart::setDirectory(const string directory) { this->directory.assign(directory); this->setSourceDir(directory); this->setOutputDir(directory); } string wsPagePart::getDirectory(void) const { return directory; } void wsPagePart::printSync(void) { if(!this->getSyncPrinted()) { if((__wsmake_get_level()>=2)||(this->getStat() != STATTYPE_NOCHANGE)) { this->getPageGroup()->printStatType(this->getStat()); __wsmake_print(1,"Part : %-30s", this->getOutputPage().c_str()); __wsmake_print(1,"\n"); } this->setSyncPrinted(1); } }