About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
libFAUDES

Sections

Index

flxinstall.cpp

Go to the documentation of this file.
00001 /** flxinstall.spp Utility to create/install/remove faudes-lua-extensions */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005 Copyright (C) 2011 Thomas Moor
00006 
00007 This library is free software; you can redistribute it and/or
00008 modify it under the terms of the GNU Lesser General Public
00009 License as published by the Free Software Foundation; either
00010 version 2.1 of the License, or (at your option) any later version.
00011 
00012 This library is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 Lesser General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public
00018 License along with this library; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00020    
00021 
00022 
00023 #include <string>
00024 #include <set>
00025 #include <cctype>
00026 #include <cstdlib>
00027 #include <ctime>
00028 #include <iostream>
00029 #include <fstream>
00030 #include "corefaudes.h"
00031 
00032 
00033 using namespace faudes;
00034 
00035 // ******************************************************************
00036 // error exit
00037 // ******************************************************************
00038 
00039 void usage_exit(const std::string& rMessage="") {
00040   // ui hints
00041   if(rMessage!="") {
00042     std::cerr << "" << std::endl;
00043     std::cerr << "flxinstall: " << rMessage << ": ERROR." << std::endl;
00044     std::cerr << "" << std::endl;
00045     exit(1);
00046   }
00047   std::cerr << "flxinstall: " << FDVersionString()  << std::endl;
00048   std::cerr << "" << std::endl;
00049   std::cerr << "utility to create/install/remove faudes-lua-extension "<< std::endl;
00050   std::cerr << std::endl << "usage: " << std::endl;
00051   std::cerr << "flxinstall  <mode>  <input-file(s)> <output-file/path>" << std::endl;
00052   std::cerr << "with <mode> as follows:" << std::endl;
00053   std::cerr << " -c  create extension (*.flx file) from input files" << std::endl;
00054   std::cerr << " -i  install extension (*.flx file) to libFAUDES installation" << std::endl;
00055   std::cerr << " -r  remove extensions from libFAUDES installation" << std::endl;
00056   std::cerr << " -x  extract extension (*.flx file) to output directory" << std::endl;
00057   std::cerr << std::endl;
00058   std::cerr << "note: options may overwrite the default target layout" << std::endl;
00059   exit(1);
00060 }
00061 
00062 
00063 // ******************************************************************
00064 // Configuration
00065 // ******************************************************************
00066 
00067 
00068 std::string mXmlSeparator = "<!-- ================================================================================ -->";
00069 
00070 
00071 // source/contents/detination
00072 std::set < std::string > mSourceFiles;
00073 std::string mSourceFile;
00074 std::string mTarget;
00075 std::string mExtensionName;
00076 std::set < std::string > mReferencePages;
00077 std::set < std::string > mImageFiles;
00078 std::set < std::string > mLuaFunctions;
00079 
00080 
00081 // destination layout (effective, defaults to libfaudes std)
00082 std::string mFaudesBase;
00083 std::string mFaudesBin;
00084 std::string mFaudesBinLuafaudes;
00085 std::string mFaudesBinLuaflx;
00086 std::string mFaudesBinRef2html;
00087 std::string mFaudesBinLua2ref;
00088 std::string mFaudesDoc;
00089 std::string mFaudesDocCss;
00090 std::string mFaudesDocToc;
00091 std::string mFaudesDocRti;
00092 std::string mFaudesDocNavigation;
00093 std::string mFaudesDocRegistry;
00094 std::string mFaudesDocLuafaudes;
00095 std::string mFaudesDocTemp;
00096 std::string mFaudesDocImages;
00097 
00098 
00099 
00100 // ******************************************************************
00101 // helper: make/remove dir
00102 // ******************************************************************
00103 
00104 // mkdir (silently fails if file exists)
00105 void MakeDirectory(const std::string& rPath, const std::string& rDir) {
00106   std::set< std::string > files=ReadDirectory(rPath);
00107   if(files.find(rDir)== files.end()) {
00108     std::cerr << "flxinstall: creating dir \"" << rPath << DirSeparator() << rDir << "\"" << std::endl;
00109     int sysret=std::system(std::string("mkdir " + rPath +DirSeparator() + rDir).c_str());
00110   }
00111 }
00112 
00113 
00114 // remove unix hidden files from list
00115 std::set < std::string >  EraseHiddenFiles(const std::set < std::string > & src) {
00116   std::set < std::string > res;
00117   for(std::set < std::string >::iterator fit=src.begin(); fit!=src.end(); fit++) {
00118     if(*fit=="") continue;
00119     if((*fit).at(0)=='.') continue;
00120     res.insert(*fit);
00121   }
00122   return res;
00123 }
00124 
00125 
00126 
00127 // ******************************************************************
00128 // helper: lua to ref process
00129 // ******************************************************************
00130 
00131 void Lua2ref(const std::string& rLuaFile, const std::string& rRefFile="") {
00132   // bail out 
00133   if(mFaudesBinLua2ref=="") {
00134     std::cerr << "flxinstall: ignoring lua script \"" << rLuaFile << "\"" << std::endl;
00135     return;
00136   }
00137   // set up target
00138   std::string dst=rRefFile;
00139   if(dst=="") {
00140     dst=PrependDirectory(ExtractDirectory(rLuaFile),ExtractBasename(rLuaFile)+ ".fref");
00141   }
00142   // set up command
00143   std::string cmd= mFaudesBinLua2ref + " " + rLuaFile + " > " + dst;
00144   // run 
00145   std::cerr << "flxinstall: converting lua script \"" << rLuaFile << "\"" << std::endl;
00146   int sysret=std::system(cmd.c_str());
00147   if(sysret!=0) {
00148     std::cerr << "flxinstall: error when converting lua script \"" << rLuaFile << "\"" << std::endl;
00149     usage_exit();
00150   }
00151     
00152 }
00153 
00154 
00155 // ******************************************************************
00156 // helper: copy files
00157 // ******************************************************************
00158 
00159 // extract and copy token section
00160 void InsertSection(TokenReader& rTr, TokenWriter& rTw, const std::string& mLabel) {
00161   // get begin
00162   Token btag;
00163   rTr.ReadBegin(mLabel,btag);
00164   // copy section
00165   rTw.Write(btag);
00166   std::string scttext = rTr.ReadSection();
00167   rTw.WriteCharacterData(scttext);
00168   rTw.WriteEnd(mLabel);    
00169   // read end tag
00170   rTr.ReadEnd(mLabel);
00171 }
00172 
00173 // extract and copy page data
00174 void InsertReferencePage(TokenReader& rTr, TokenWriter& rTw, const std::string mSection="") {
00175   // get begin
00176   Token btag;
00177   rTr.ReadBegin("ReferencePage",btag);
00178   // fix attributes
00179   if(!btag.ExistsAttributeString("chapter")) 
00180     btag.InsAttributeString("chapter","Reference");
00181   if(!btag.ExistsAttributeString("section")) 
00182   if(mSection!="")
00183     btag.InsAttributeString("section",mSection);
00184   // copy section
00185   rTw.Write(btag);
00186   std::string scttext = rTr.ReadSection();
00187   rTw.WriteCharacterData(scttext);
00188   rTw.WriteEnd("ReferencePage");    
00189   // read end tag
00190   rTr.ReadEnd("ReferencePage");
00191 }
00192 
00193 
00194 // extract and copy luafunction
00195 void InsertLuaFunction(TokenReader& rTr, TokenWriter& rTw) {
00196   // get begin
00197   Token btag;
00198   rTr.ReadBegin("LuaFunctionDefinition",btag);
00199   // copy section
00200   rTw.Write(btag);
00201   std::string scttext = rTr.ReadSection();
00202   rTw.WriteCharacterData(scttext);
00203   rTw.WriteEnd("LuaFunctionDefinition");    
00204   // read end tag
00205   rTr.ReadEnd("LuaFunctionDefinition");
00206 }
00207 
00208 
00209 
00210 // extract and copy tutorial (from xml to plain)
00211 void InsertPlainLuaTutorial(TokenReader& rTr, TokenWriter& rTw) {
00212   // get begin
00213   Token btag;
00214   rTr.ReadBegin("LuaTutorial",btag);
00215   // copy cdata
00216   std::string codestr;
00217   Token code;
00218   while(rTr.Peek(code)) {
00219     if(!code.IsString()) break;
00220     rTr.Get(code);
00221     codestr.append(code.StringValue());
00222   }
00223   *rTw.Streamp() << codestr;
00224   // read end tag
00225   rTr.ReadEnd("LuaTutorial");
00226 }
00227 
00228 
00229 // extract and copy tutorial (from plain to xml)
00230 void InsertLuaTutorial(TokenReader& rTr, TokenWriter& rTw) {
00231   // read script file to buffer
00232   char* buffer=0;
00233   long int size=0;
00234   try{
00235     rTr.Rewind();
00236     rTr.Streamp()->seekg(0, std::ios::end);
00237     std::streampos last = rTr.Streamp()->tellg();
00238     rTr.Streamp()->seekg(0, std::ios::beg);
00239     std::streampos first = rTr.Streamp()->tellg();
00240     size=(long int) last-first;
00241     buffer = new char[last-first]; 
00242     rTr.Streamp()->read(buffer, last-first);
00243     rTr.Rewind();
00244   } catch (std::ios::failure&) {
00245     std::cerr << "flxinstall: io error when reading  \"" << rTr.FileName() << "\": ERROR." << std::endl;
00246     exit(1);
00247   }
00248   // convert (better solution?)
00249   std::string bufferstr;
00250   bufferstr.assign(buffer,size);
00251   // relative destination
00252   std::string name=rTr.FileName();
00253   name=ExtractFilename(name);
00254   // write cdata encoded entry
00255   Token btag;
00256   btag.SetBegin("LuaTutorial");
00257   btag.InsAttributeString("name",name);
00258   rTw.Write(btag);
00259   rTw.WriteVerbatim(bufferstr);
00260   rTw.WriteEnd("LuaTutorial");
00261   // discard buffer
00262   delete buffer;
00263 }
00264 
00265 
00266 
00267 // copy source as binary image file
00268 void InsertImageFile(TokenReader& rTr,TokenWriter& rTw) {
00269   // read image file to buffer
00270   char* buffer=0;
00271   long int size=0;
00272   try{
00273     rTr.Rewind();
00274     rTr.Streamp()->seekg(0, std::ios::end);
00275     std::streampos last = rTr.Streamp()->tellg();
00276     rTr.Streamp()->seekg(0, std::ios::beg);
00277     std::streampos first = rTr.Streamp()->tellg();
00278     size=(long int) last-first;
00279     buffer = new char[last-first]; 
00280     rTr.Streamp()->read(buffer, last-first);
00281     rTr.Rewind();
00282   } catch (std::ios::failure&) {
00283     std::cerr << "flxinstall: io error when reading  \"" << rTr.FileName() << "\": ERROR." << std::endl;
00284     exit(1);
00285   }
00286   // relative destination
00287   std::string name=rTr.FileName();
00288   name=ExtractFilename(name);
00289   // write Base64 encoded entry
00290   Token btag;
00291   btag.SetBegin("ImageFile");
00292   btag.InsAttributeString("name",name);
00293   rTw.Write(btag);
00294   rTw.WriteBinary(buffer,size);
00295   rTw << "\n";
00296   rTw.WriteEnd("ImageFile");
00297   // discard buffer
00298   delete buffer;
00299 }
00300 
00301 
00302 
00303 // copy source as binary data file
00304 void InsertDataFile(TokenReader& rTr,TokenWriter& rTw) {
00305   // read data file to buffer
00306   char* buffer=0;
00307   long int size=0;
00308   try{
00309     rTr.Rewind();
00310     rTr.Streamp()->seekg(0, std::ios::end);
00311     std::streampos last = rTr.Streamp()->tellg();
00312     rTr.Streamp()->seekg(0, std::ios::beg);
00313     std::streampos first = rTr.Streamp()->tellg();
00314     size=(long int) last-first;
00315     buffer = new char[last-first]; 
00316     rTr.Streamp()->read(buffer, last-first);
00317     rTr.Rewind();
00318   } catch (std::ios::failure&) {
00319     std::cerr << "flxinstall: io error when reading  \"" << rTr.FileName() << "\": ERROR." << std::endl;
00320     exit(1);
00321   }
00322   // relative destination
00323   std::string name=rTr.FileName();
00324   name=ExtractFilename(name);
00325   // write Base64 encoded entry
00326   Token btag;
00327   btag.SetBegin("DataFile");
00328   btag.InsAttributeString("name",name);
00329   rTw.Write(btag);
00330   rTw.WriteBinary(buffer,size);
00331   rTw << "\n";
00332   rTw.WriteEnd("DataFile");
00333   // discard buffer
00334   delete buffer;
00335 }
00336 
00337 
00338 
00339 
00340 // ******************************************************************
00341 // create
00342 // ******************************************************************
00343 
00344 
00345 // control
00346 void CreateExtensionFile(void) {
00347 
00348   // ************ pass 1: inspect sources
00349 
00350   // traverse images
00351   for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
00352     // test extension
00353     std::string ext=ExtractExtension(*fit);
00354     std::string bas=ExtractBasename(*fit);
00355     // cases: binary
00356     if( (ext=="png") || (ext=="svg") || (ext=="jpeg") || (ext=="jpg") ) {
00357       std::cerr << "flxinstall: scanning image file \"" << *fit << "\"" << std::endl;
00358       mImageFiles.insert(bas);
00359     } 
00360   }
00361   // traverse luafunctions
00362   for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
00363     // test extension
00364     std::string ext=ExtractExtension(*fit);
00365     std::string bas=ExtractBasename(*fit);
00366     // cases: luafunction
00367     if(ext=="rti" && mImageFiles.find(bas)==mImageFiles.end()) {
00368       std::cerr << "flxinstall: scanning luafunction \"" << *fit << "\"" << std::endl;
00369       TokenReader tr(*fit);
00370       Token btag;
00371       tr.ReadBegin("LuaFunctionDefinition",btag);
00372       if(!btag.ExistsAttributeString("name")) {
00373         std::cerr << "flxinstall: name not specified " << tr.FileLine() << ": ERROR." << std::endl;
00374         exit(1);
00375       }
00376       // extract name and space
00377       std::string name;
00378       std::string space;
00379       name=btag.AttributeStringValue("name");
00380       size_t pos=name.find("::"); 
00381       if(pos!=std::string::npos) {
00382         space=name.substr(0,pos);
00383         name=name.substr(pos+2);
00384       }
00385       // insist in matching space
00386       if(space!="" && mExtensionName!="" && space!=mExtensionName) {
00387         std::cerr << "flxinstall: namespace must match extension name" << tr.FileLine() << ": ERROR." << std::endl;
00388         exit(1);
00389       }
00390       mExtensionName=space;
00391       // done
00392       tr.ReadEnd("LuaFunctionDefinition");
00393     }
00394   }
00395   // traverse ref pages
00396   for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
00397     // test extension
00398     std::string ext=ExtractExtension(*fit);
00399     std::string bas=ExtractBasename(*fit);
00400     // cases: reference page
00401     if(ext=="fref" && mImageFiles.find(bas)==mImageFiles.end()) {
00402       std::cerr << "flxinstall: scanning reference page \"" << *fit << "\"" << std::endl;
00403       TokenReader tr(*fit);
00404       Token btag;
00405       tr.ReadBegin("ReferencePage",btag);
00406       if(!btag.ExistsAttributeString("page")) {
00407         std::cerr << "flxinstall: page not specified " << tr.FileLine() << ": ERROR." << std::endl;
00408         exit(1);
00409       }
00410       if(!btag.ExistsAttributeString("title")) {
00411         std::cerr << "flxinstall: title not specified " << tr.FileLine() << std::endl;
00412         exit(1);
00413       }
00414       if(btag.ExistsAttributeString("chapter")) 
00415       if(btag.AttributeStringValue("chapter")!="Reference") {
00416         std::cerr << "flxinstall: chapter must be \"Reference\" " << tr.FileLine() << ": ERROR." << std::endl;
00417         exit(1);
00418       }
00419       if(btag.ExistsAttributeString("section")) 
00420       if(mExtensionName.size()==0) {
00421         mExtensionName=btag.AttributeStringValue("section");
00422       }
00423       if(btag.ExistsAttributeString("section")) 
00424       if(mExtensionName!=btag.AttributeStringValue("section")) {
00425         std::cerr << "flxinstall: section name \"" << mExtensionName << "\" expected " 
00426              << tr.FileLine() << ": ERROR." << std::endl;
00427         exit(1);
00428       }
00429       std::string page=btag.AttributeStringValue("page");
00430       std::transform(page.begin(), page.end(), page.begin(), tolower);
00431       if(mReferencePages.find(page)!=mReferencePages.end()) {
00432         std::cerr << "flxinstall: double page label \"" << page << "\" "
00433             << tr.FileLine() << ": ERROR." << std::endl;
00434         exit(1);
00435       }
00436       mReferencePages.insert(page);
00437       tr.ReadEnd("ReferencePage");
00438     }
00439   }
00440   if(mReferencePages.find("index")==mReferencePages.end()) {
00441     std::cerr << "flxinstall: missing index page, will be generated on installation." << std::endl;
00442   }
00443 
00444 
00445   // ************ pass 2: read/copy sources
00446 
00447   // set up target
00448   TokenWriter* ptw=0;
00449   if(mTarget=="") {
00450     mTarget=mExtensionName + ".flx";
00451     std::transform(mTarget.begin(), mTarget.end(), mTarget.begin(), tolower);
00452   }
00453   if(mTarget!="-")
00454     ptw=new TokenWriter(mTarget,"LuaExtension");
00455   else    
00456     ptw=new TokenWriter(TokenWriter::Stdout);
00457   // indicate tool version
00458   *ptw->Streamp() << "<!-- flxinstall " << FDVersionString() << " -->" << std::endl;
00459   // start tag
00460   Token btag;
00461   btag.SetBegin("LuaExtension");
00462   btag.InsAttributeString("name",mExtensionName);
00463   ptw->Write(btag);
00464   // traverse files
00465   for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
00466     // test extension
00467     std::string ext=ExtractExtension(*fit);
00468     std::string bas=ExtractBasename(*fit);
00469     // cases: reference page
00470     if(ext=="fref" && mImageFiles.find(bas)==mImageFiles.end()) {
00471       std::cerr << "flxinstall: appending reference page from \"" << *fit << "\"" << std::endl;
00472       *ptw << "\n" << "\n";
00473       *ptw->Streamp() << mXmlSeparator << std::endl;
00474       *ptw->Streamp() << mXmlSeparator << std::endl;
00475       *ptw->Streamp() << mXmlSeparator << std::endl;
00476       *ptw->Streamp() << "<!-- reference page from source \"" << *fit << "\" -->" << std::endl;
00477       *ptw << "\n" << "\n";
00478       TokenReader tr(*fit);
00479       InsertReferencePage(tr,*ptw,mExtensionName);
00480       continue;
00481     }  
00482     // cases: code
00483     if(ext=="rti") {
00484       std::cerr << "flxinstall: appending lua function from \"" << *fit << "\"" << std::endl;
00485       *ptw << "\n" << "\n";
00486       *ptw->Streamp() << mXmlSeparator << std::endl;
00487       *ptw->Streamp() << mXmlSeparator << std::endl;
00488       *ptw->Streamp() << mXmlSeparator << std::endl;
00489       *ptw->Streamp() << "<!-- lua function from source \"" << *fit << "\" -->" << std::endl;
00490       *ptw << "\n" << "\n";
00491       TokenReader tr(*fit);
00492       InsertLuaFunction(tr,*ptw);
00493       continue;
00494     }  
00495     // cases: binary
00496     if(mImageFiles.find(bas)!=mImageFiles.end()) {
00497       std::cerr << "flxinstall: appending image/binary file from \"" << *fit << "\"" << std::endl;
00498       *ptw << "\n" << "\n";
00499       *ptw->Streamp() << mXmlSeparator << std::endl;
00500       *ptw->Streamp() << mXmlSeparator << std::endl;
00501       *ptw->Streamp() << mXmlSeparator << std::endl;
00502       *ptw->Streamp() << "<!-- binary file from source \"" << *fit << "\" -->" << std::endl;
00503       *ptw << "\n" << "\n";
00504       TokenReader tr(*fit);
00505       InsertImageFile(tr,*ptw);
00506       continue;
00507     } 
00508     // cases: tutorial
00509     if(ext=="lua") {
00510       std::cerr << "flxinstall: appending tutorial from \"" << *fit << "\"" << std::endl;
00511       *ptw << "\n" << "\n";
00512       *ptw->Streamp() << mXmlSeparator << std::endl;
00513       *ptw->Streamp() << mXmlSeparator << std::endl;
00514       *ptw->Streamp() << mXmlSeparator << std::endl;
00515       *ptw->Streamp() << "<!-- tutorial from source \"" << *fit << "\" -->" << std::endl;
00516       *ptw << "\n" << "\n";
00517       TokenReader tr(*fit);
00518       InsertLuaTutorial(tr,*ptw);
00519       continue;
00520     }  
00521     // cases: data directory
00522     if(ext=="" && bas=="data") {
00523       std::set< std::string > datafiles = ReadDirectory(*fit);
00524       datafiles=EraseHiddenFiles(datafiles);
00525       if(datafiles.size()==0) continue;
00526       std::cerr << "flxinstall: appending data files \"" << *fit << "\"" << std::endl;
00527       *ptw << "\n" << "\n";
00528       *ptw->Streamp() << mXmlSeparator << std::endl;
00529       *ptw->Streamp() << mXmlSeparator << std::endl;
00530       *ptw->Streamp() << mXmlSeparator << std::endl;
00531       *ptw->Streamp() << "<!-- data from source \"" << *fit << "\" -->" << std::endl;
00532       *ptw << "\n" << "\n";
00533       std::set< std::string >::iterator dit;
00534       for(dit=datafiles.begin();dit!=datafiles.end();dit++) {
00535   std::string srcfile=PrependDirectory(*fit,*dit);
00536         TokenReader tr(srcfile);
00537         InsertDataFile(tr,*ptw);
00538       }
00539     }  
00540   }
00541   // cleanup/close
00542   *ptw << "\n" << "\n";
00543   ptw->WriteEnd("LuaExtension"); 
00544   delete ptw;
00545 }
00546 
00547 
00548 // ******************************************************************
00549 // test libfaudes installation
00550 // ******************************************************************
00551 
00552 // inspect libfaudes distribution
00553 void TestFaudesTarget(void) {
00554   mFaudesBase=mTarget;
00555   std::set< std::string > faudesfiles = ReadDirectory(mFaudesBase);
00556   // bad dir
00557   if(faudesfiles.empty()) {
00558     std::cerr << "flxinstall: cannot open target directory \"" << mFaudesBase << "\": ERROR." << std::endl;
00559     exit(1);
00560   }
00561   // bin (allow overwrite)
00562   if(mFaudesBin=="") {
00563     mFaudesBin=mFaudesBase;
00564     if(faudesfiles.find("bin")!= faudesfiles.end())
00565       mFaudesBin=PrependDirectory(mFaudesBase,"bin");
00566   }
00567   std::set< std::string > binfiles = ReadDirectory(mFaudesBin);
00568   // ref2html
00569   mFaudesBinRef2html="";
00570   if(binfiles.find("ref2html.exe")!= binfiles.end()) {
00571     mFaudesBinRef2html=PrependDirectory(mFaudesBin,"ref2html.exe");
00572   }
00573   if(binfiles.find("ref2html")!= binfiles.end()) {
00574     mFaudesBinRef2html=PrependDirectory(mFaudesBin,"ref2html");
00575   }
00576   if(mFaudesBinRef2html=="") {
00577     std::cerr << "flxinstall: cannot open ref2html tool in \"" << mFaudesBin << "\": ERROR." << std::endl;
00578     exit(1);
00579   }
00580   // test luafaudes
00581   mFaudesBinLuafaudes="";
00582   if(binfiles.find("luafaudes.exe")!= binfiles.end()) {
00583     mFaudesBinLuafaudes=PrependDirectory(mFaudesBin,"luafaudes.exe");
00584   }
00585   if(binfiles.find("luafaudes")!= binfiles.end()) {
00586     mFaudesBinLuafaudes=PrependDirectory(mFaudesBin,"luafaudes");
00587   }
00588   if(mFaudesBinLuafaudes=="") {
00589     std::cerr << "flxinstall: cannot open luafaudes in \"" << mFaudesBin << "\": ERROR." << std::endl;
00590     exit(1);
00591   }
00592   // target flx
00593   mFaudesBinLuaflx=PrependDirectory(mFaudesBin,"luafaudes.flx");
00594   // doc (allow overwrite)
00595   if(mFaudesDoc=="") {
00596     mFaudesDoc=mFaudesBase;
00597     if(faudesfiles.find("doc")!= faudesfiles.end()) {
00598       mFaudesDoc=PrependDirectory(mFaudesDoc,"doc");
00599     } else if(faudesfiles.find("Doc")!= faudesfiles.end()) {
00600       mFaudesDoc=PrependDirectory(mFaudesDoc,"Doc");
00601     } else if(faudesfiles.find("Documentation")!= faudesfiles.end()) {
00602       mFaudesDoc=PrependDirectory(mFaudesDoc,"Documentation");
00603     } 
00604   }
00605   std::set< std::string > docfiles = ReadDirectory(mFaudesDoc);
00606   // css (allow overwrite)
00607   if(mFaudesDocCss=="") {
00608     mFaudesDocCss="faudes.css";
00609   }
00610   // registry
00611   mFaudesDocRegistry=mFaudesDoc;
00612   if(docfiles.find("registry")!= docfiles.end()) {
00613     mFaudesDocRegistry=PrependDirectory(mFaudesDoc,"registry");
00614   } else if(docfiles.find("Registry")!= faudesfiles.end()) {
00615     mFaudesDocRegistry=PrependDirectory(mFaudesDoc,"Registry");
00616   } else {
00617     std::cerr << "flxinstall: cannot open registry in \"" << mFaudesDoc << "\": ERROR." << std::endl;
00618     exit(1);
00619   }
00620   std::set< std::string > regfiles = ReadDirectory(mFaudesDocRegistry);
00621   // luafaudes doc (default: non-existant)
00622   mFaudesDocLuafaudes="";
00623   if(docfiles.find("luafaudes")!= docfiles.end()) {
00624     mFaudesDocLuafaudes=PrependDirectory(mFaudesDoc,"luafaudes");
00625   } else if(docfiles.find("Luafaudes")!= docfiles.end()) {
00626     mFaudesDocLuafaudes=PrependDirectory(mFaudesDoc,"Luafaudes");
00627   } 
00628   // lua2ref 
00629   if(mFaudesDocLuafaudes!="") {
00630     mFaudesBinLua2ref=mFaudesBase + DirSeparator() + "tools" + DirSeparator() + "lua2ref" + DirSeparator() + "lua2ref";
00631     if(binfiles.find("lua2ref.exe")!= binfiles.end()) {
00632       mFaudesBinLua2ref=PrependDirectory(mFaudesBin,"lua2ref.exe");
00633     }
00634     if(binfiles.find("lua2ref")!= binfiles.end()) {
00635       mFaudesBinLua2ref=PrependDirectory(mFaudesBin,"lua2ref");
00636     }
00637     if(!FileExists(mFaudesBinLua2ref)) mFaudesBinLua2ref=""; // don't convert on MsWin
00638   }
00639   // rti (allow overwrite)
00640   if(mFaudesDocRti=="") {
00641     if(regfiles.find("libfaudes.rti")!= regfiles.end()) {
00642       mFaudesDocRti=PrependDirectory(mFaudesDocRegistry,"libfaudes.rti");
00643     } else {
00644       std::cerr << "flxinstall: cannot open libfaudes.rti in \"" << mFaudesDocRegistry << "\": ERROR." << std::endl;
00645       exit(1);
00646     }
00647   }
00648   // cnav (allow overwrite)
00649   if(mFaudesDocNavigation=="") {
00650     if(docfiles.find("faudes_navigation.include_fref")!= regfiles.end()) {
00651       mFaudesDocNavigation=PrependDirectory(mFaudesDoc,"faudes_navigation.include_fref");
00652     } else {
00653       std::cerr << "flxinstall: cannot open navigation file in \"" << mFaudesDoc << "\": ERROR." << std::endl;
00654       exit(1);
00655     }
00656   }
00657   // images
00658   mFaudesDocImages=mFaudesDoc;
00659   if(docfiles.find("faudes_images")!= docfiles.end()) {
00660     mFaudesDocImages=PrependDirectory(mFaudesDoc,"faudes_images");
00661   } else {
00662     std::cerr << "flxinstall: cannot open faudes_images in \"" << mFaudesDoc << "\": ERROR." << std::endl;
00663     exit(1);
00664   }
00665   // temp
00666   mFaudesDocTemp=PrependDirectory(mFaudesDoc,"tmp_flx");
00667   if(docfiles.find("tmp_flx")== docfiles.end()) {
00668     std::cerr << "flxinstall: creating temp dir \"" << mFaudesDocTemp << "\"" << std::endl;
00669     int sysret=std::system(std::string("mkdir " + mFaudesDocTemp).c_str());
00670   } 
00671   mFaudesDocToc=PrependDirectory(mFaudesDocTemp,"toc");
00672 }
00673 
00674  
00675 // ******************************************************************
00676 // extract reference pages
00677 // ******************************************************************
00678 
00679 
00680 void  XtractReferencePages(TokenReader& rTr, const std::string& rDstDir) {
00681   // read outer tag
00682   Token btag;
00683   rTr.Rewind();
00684   rTr.ReadBegin("LuaExtension",btag);
00685   if(!btag.ExistsAttributeString("name")) {
00686     std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl;
00687     exit(1);
00688   }
00689   mExtensionName=btag.AttributeStringValue("name");  
00690   // scan for reference page sections
00691   while(!rTr.Eos("LuaExtension")) {
00692     rTr.Peek(btag);
00693     // skip tokens
00694     if(!btag.IsBegin()) {
00695       rTr.Get(btag);
00696       continue;
00697     }
00698     // skip sections
00699     if(btag.StringValue()!="ReferencePage") {
00700       rTr.ReadBegin(btag.StringValue());
00701       rTr.ReadEnd(btag.StringValue());
00702       continue;
00703     }
00704     // extract title & friends
00705     std::string title="libFAUDES Reference";
00706     if(btag.ExistsAttributeString("title")) 
00707       title=btag.AttributeStringValue("title");
00708     std::string chapter="Reference";
00709     if(btag.ExistsAttributeString("chapter")) 
00710       chapter=btag.AttributeStringValue("chapter");
00711     std::string section="";
00712     if(btag.ExistsAttributeString("section")) 
00713       section=btag.AttributeStringValue("section");
00714     std::string page="";
00715     if(btag.ExistsAttributeString("page")) 
00716       page=btag.AttributeStringValue("page");
00717     // insist in page and section
00718     if(page=="" || section=="") {
00719       std::cerr << "flxinstall: skipping undefined page at " << rTr.FileLine() << std::endl;
00720       rTr.ReadBegin("ReferencePage",btag);
00721       rTr.ReadEnd("ReferencePage");
00722       continue;
00723     } 
00724     // normalize & report 
00725     std::transform(section.begin(), section.end(), section.begin(), tolower);
00726     std::transform(page.begin(), page.end(), page.begin(), tolower);
00727     // basename
00728     std::string basename= section + "_" + page;
00729     mReferencePages.insert(basename);
00730     // dst file
00731     std::string dstfile=rDstDir + DirSeparator() + basename + ".fref";
00732     std::cerr << "flxinstall: extracting reference page to \"" << dstfile << "\"" << std::endl;
00733     TokenWriter dst(dstfile);
00734     InsertReferencePage(rTr,dst);
00735   }  
00736 }
00737 
00738 // ******************************************************************
00739 // extract image files
00740 // ******************************************************************
00741 
00742 
00743 void  XtractImageFiles(TokenReader& rTr,const std::string& rDstDir) {
00744   // read outer tag
00745   Token btag;
00746   rTr.Rewind();
00747   rTr.ReadBegin("LuaExtension",btag);
00748   if(!btag.ExistsAttributeString("name")) {
00749     std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl;
00750     exit(1);
00751   }
00752   mExtensionName=btag.AttributeStringValue("name");  
00753   // scan for image files
00754   while(!rTr.Eos("LuaExtension")) {
00755     rTr.Peek(btag);
00756     // skip tokens
00757     if(!btag.IsBegin()) {
00758       rTr.Get(btag);
00759       continue;
00760     }
00761     // skip sections
00762     if(btag.StringValue()!="ImageFile") {
00763       rTr.ReadBegin(btag.StringValue());
00764       rTr.ReadEnd(btag.StringValue());
00765       continue;
00766     }
00767     // read begin tag
00768     rTr.ReadBegin("ImageFile",btag);
00769     std::string name=btag.AttributeStringValue("name");
00770     if(name==""){
00771       std::cerr << "flxinstall: image file must specify name " << rTr.FileLine() << std::endl;
00772       rTr.ReadEnd("ImageFile");
00773       continue;
00774     } 
00775     // read data
00776     Token data;
00777     rTr.Get(data);
00778     if(!data.IsBinary()){
00779       std::cerr << "flxinstall: skipping invalid image data " << rTr.FileLine() << std::endl;
00780       rTr.ReadEnd("ImageFile");
00781       continue;
00782     } 
00783     // dst file
00784     std::transform(name.begin(), name.end(), name.begin(), tolower);
00785     std::string dstfile=rDstDir + DirSeparator() + name;
00786     std::cerr << "flxinstall: extracting image to \"" << dstfile << "\"" << std::endl;
00787     // setup stream
00788     std::fstream fsout;
00789     fsout.exceptions(std::ios::badbit|std::ios::failbit);
00790     try{
00791       fsout.open(dstfile.c_str(), std::ios::out | std::ios::binary); 
00792       fsout.write(data.StringValue().c_str(),data.StringValue().size());
00793       fsout.close();
00794     } 
00795     catch (std::ios::failure&) {
00796       std::cerr << "flxinstall: file io error when writing  \"" << dstfile << "\"" << std::endl;
00797     }
00798     // read end tag
00799     rTr.ReadEnd("ImageFile");
00800   }  
00801 }
00802 
00803 
00804 // ******************************************************************
00805 // extract lua code
00806 // ******************************************************************
00807 
00808 
00809 
00810 void  XtractLuaFunctions(TokenReader& rTr, TokenWriter& rTw) {
00811   // read outer tag
00812   Token btag;
00813   rTr.Rewind();
00814   rTr.ReadBegin("LuaExtension",btag);
00815   if(!btag.ExistsAttributeString("name")) {
00816     std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl;
00817     exit(1);
00818   }
00819   mExtensionName=btag.AttributeStringValue("name");  
00820   // scan for reference page sections
00821   while(!rTr.Eos("LuaExtension")) {
00822     rTr.Peek(btag);
00823     // skip tokens
00824     if(!btag.IsBegin()) {
00825       rTr.Get(btag);
00826       continue;
00827     }
00828     // skip sections
00829     if(btag.StringValue()!="LuaFunctionDefinition") {
00830       rTr.ReadBegin(btag.StringValue());
00831       rTr.ReadEnd(btag.StringValue());
00832       continue;
00833     }
00834     // extract title & friends
00835     std::string name;
00836     std::string space;
00837     if(btag.ExistsAttributeString("name")){
00838       name=btag.AttributeStringValue("name");
00839       size_t pos=name.find("::"); 
00840       if(pos!=std::string::npos) {
00841         space=name.substr(0,pos);
00842         name=name.substr(pos+2);
00843       }
00844     }
00845     // insist in name 
00846     if(name=="") {
00847       std::cerr << "flxinstall: skipping undefined lua function at " << rTr.FileLine() << std::endl;
00848       rTr.ReadBegin("LuaFunctionDefinition",btag);
00849       rTr.ReadEnd("LuafunctionDefinition");
00850       continue;
00851     } 
00852     // insist in space to match 
00853     /*
00854     if(space!=mExtensionName) {
00855       std::cerr << "flxinstall: skipping undefined lua function at " << rTr.FileLine() << std::endl;
00856       rTr.ReadBegin("LuaFunctionDefinition",btag);
00857       rTr.ReadEnd("LuafunctionDefinition");
00858       continue;
00859     } 
00860     */
00861     // record
00862     mLuaFunctions.insert(name);
00863     // copy
00864     std::cerr << "flxinstall: extracting lua function \"" << name << "\"" << std::endl;
00865     *rTw.Streamp() << mXmlSeparator << std::endl;
00866     *rTw.Streamp() << mXmlSeparator << std::endl;
00867     *rTw.Streamp() << "<!-- lua function from lua-extension " << rTr.FileLine() << " -->" << std::endl;
00868     rTw << "\n" << "\n";
00869     InsertLuaFunction(rTr,rTw);
00870   }  
00871 }
00872 
00873 // ******************************************************************
00874 // extract lua tutorials
00875 // ******************************************************************
00876 
00877 void  XtractLuaTutorials(TokenReader& rTr, const std::string& rDstDir) {
00878   // read outer tag
00879   Token btag;
00880   rTr.Rewind();
00881   rTr.ReadBegin("LuaExtension",btag);
00882   if(!btag.ExistsAttributeString("name")) {
00883     std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl;
00884     exit(1);
00885   }
00886   mExtensionName=btag.AttributeStringValue("name");  
00887   // scan for reference page sections
00888   while(!rTr.Eos("LuaExtension")) {
00889     rTr.Peek(btag);
00890     // skip tokens
00891     if(!btag.IsBegin()) {
00892       rTr.Get(btag);
00893       continue;
00894     }
00895     // skip sections
00896     if(btag.StringValue()!="LuaTutorial") {
00897       rTr.ReadBegin(btag.StringValue());
00898       rTr.ReadEnd(btag.StringValue());
00899       continue;
00900     }
00901     // test for name
00902     std::string name=btag.AttributeStringValue("name");
00903     if(name==""){
00904       std::cerr << "flxinstall: lua tutorial must specify name " << rTr.FileLine() << std::endl;
00905       rTr.ReadEnd("LuaTutorial");
00906       continue;
00907     } 
00908     // set up destination and copy
00909     std::transform(name.begin(), name.end(), name.begin(), tolower);
00910     std::string dstfile=rDstDir + DirSeparator() + name;
00911     std::cerr << "flxinstall: extracting lua tutorial to \"" << dstfile << "\"" << std::endl;
00912     TokenWriter tw(dstfile);
00913     InsertPlainLuaTutorial(rTr,tw);
00914   }
00915 }
00916 
00917 // ******************************************************************
00918 // generate default reference page
00919 // ******************************************************************
00920 
00921 void DefaultIndexPage(const std::string& rDstDir) {
00922   // name of index files
00923   std::string index=mExtensionName + "_index";
00924   std::transform(index.begin(), index.end(), index.begin(), tolower);
00925   // test existence
00926   if(mReferencePages.find(index)!=mReferencePages.end()) {
00927     std::cerr << "flxinstall: index page provided" << std::endl;
00928     return;
00929   } 
00930   // error case
00931   if(mReferencePages.size()>0) {
00932     std::cerr << "flxinstall: reference page missing: \"" << index << ".fref\": ERROR" << std::endl;
00933     exit(1);
00934   } 
00935   // generates defaultindex page
00936   std::cerr << "flxinstall: generate index page" << std::endl;
00937   TokenWriter tw(rDstDir + DirSeparator() + index + ".fref","ReferencePage");
00938   *tw.Streamp() << "<!-- flxinstall " << FDVersionString() << ": auto generated index -->" << std::endl;
00939   *tw.Streamp() << "<ReferencePage chapter=\"Reference\" section=\"" << mExtensionName << 
00940     "\" page=\"Index\" title=\""<< mExtensionName << " Index\" >" << std::endl;
00941   // headline
00942   *tw.Streamp() << "<h1> " << mExtensionName << ": Functions </h1>" << std::endl;
00943   // list functions
00944   std::set< std::string >::iterator fit;
00945   for(fit=mLuaFunctions.begin(); fit!= mLuaFunctions.end(); fit++) {
00946     *tw.Streamp() << "<ffnct_reference name=\"" << *fit << "\" />" << std::endl;
00947   }
00948   // done
00949   *tw.Streamp() << "</ReferencePage>" << std::endl;
00950 } 
00951 
00952 
00953 
00954 
00955 // ******************************************************************
00956 // install extension
00957 // ******************************************************************
00958 
00959 // control
00960 void InstallExtensionFiles(void) {
00961 
00962   // clean tmp
00963   std::set< std::string > tmpfiles = ReadDirectory(mFaudesDocTemp);
00964   for(std::set < std::string >::iterator fit=tmpfiles.begin(); fit!=tmpfiles.end(); fit++) {
00965     std::string dfile=PrependDirectory(mFaudesDocTemp,*fit);
00966     if(!RemoveFile(dfile)) {
00967       std::cerr << "flxinstall: failed to remove \"" << *fit << "\"" << std::endl;
00968     };
00969   }
00970 
00971   // prepare luafaudes.flx
00972   TokenWriter twflx(mFaudesBinLuaflx);
00973 
00974   // traverse files and extract
00975   for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
00976     // test extension
00977     std::string ext=ExtractExtension(*fit);
00978     std::string bas=ExtractBasename(*fit);
00979     // cases: flx
00980     if(ext=="flx") {
00981       std::cerr << "flxinstall: extracting lua-extension from \"" << *fit << "\"" << std::endl;
00982       // clear extension context
00983       mReferencePages.clear();
00984       mLuaFunctions.clear();
00985       mExtensionName="";
00986       // extract component files
00987       TokenReader rTr(*fit);
00988       XtractReferencePages(rTr,mFaudesDocTemp);
00989       XtractLuaTutorials(rTr,mFaudesDocTemp);
00990       XtractImageFiles(rTr,mFaudesDocImages);
00991       XtractLuaFunctions(rTr,twflx);
00992       // autogenerate index if necessary
00993       DefaultIndexPage(mFaudesDocTemp);      
00994       continue;
00995     } 
00996   }
00997   twflx.Flush();
00998 
00999   // convert lua tutorials to fref if necessary
01000   /*std::set< std::string > */tmpfiles = ReadDirectory(mFaudesDocTemp);
01001   for(std::set < std::string >::iterator fit=tmpfiles.begin(); fit!=tmpfiles.end(); fit++) {
01002     std::string ext=ExtractExtension(*fit);
01003     std::string bas=ExtractBasename(*fit);
01004     std::string ffile=PrependDirectory(mFaudesDocTemp,*fit);
01005     // skip non-lua
01006     if(ext!="lua") continue;
01007     // test for corresponding fref file
01008     std::string fref = ExtractBasename(*fit) + ".fref";
01009     if(tmpfiles.find(fref)!=tmpfiles.end()) continue;
01010     // process
01011     Lua2ref(ffile);
01012   }
01013 
01014   // collect all fref files
01015   std::set< std::string > stdfreffiles = ReadDirectory(mFaudesDocRegistry);
01016   std::set< std::string > luafreffiles = ReadDirectory(mFaudesDocLuafaudes);
01017   std::set< std::string > extfreffiles = ReadDirectory(mFaudesDocTemp);
01018   std::set< std::string > freffiles;
01019   std::set< std::string > frefbase;
01020   for(std::set < std::string >::iterator fit=stdfreffiles.begin(); fit!=stdfreffiles.end(); fit++) {
01021     std::string ext=ExtractExtension(*fit);
01022     std::string bas=ExtractBasename(*fit);
01023     std::string ffile=PrependDirectory(mFaudesDocRegistry,*fit);
01024     if(ext!="fref") continue;
01025     if((*fit).at(0)=='.') continue;
01026     if(frefbase.find(bas)!=frefbase.end()){
01027       std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from std dist: ERROR." << std::endl;
01028       exit(1);
01029     }
01030     freffiles.insert(ffile);
01031     frefbase.insert(bas);
01032   }
01033   for(std::set < std::string >::iterator fit=luafreffiles.begin(); fit!=luafreffiles.end(); fit++) {
01034     std::string ext=ExtractExtension(*fit);
01035     std::string bas=ExtractBasename(*fit);
01036     std::string ffile=PrependDirectory(mFaudesDocLuafaudes,*fit);
01037     if(ext!="fref") continue;
01038     if((*fit).at(0)=='.') continue;
01039     if(frefbase.find(bas)!=frefbase.end()){
01040       std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from lua doc: ERROR." << std::endl;
01041       exit(1);
01042     }
01043     freffiles.insert(ffile);
01044     frefbase.insert(bas);
01045   }
01046   for(std::set < std::string >::iterator fit=extfreffiles.begin(); fit!=extfreffiles.end(); fit++) {
01047     std::string ext=ExtractExtension(*fit);
01048     std::string bas=ExtractBasename(*fit);
01049     std::string ffile=PrependDirectory(mFaudesDocTemp,*fit);
01050     if(ext!="fref") continue;
01051     if((*fit).at(0)=='.') continue;
01052     if(frefbase.find(bas)!=frefbase.end()){
01053       std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from ext: ERROR." << std::endl;
01054       exit(1);
01055     }
01056     freffiles.insert(ffile);
01057     frefbase.insert(bas);
01058   }
01059 
01060   // setup toc
01061   std::string toccmd;
01062   for(std::set < std::string >::iterator fit=freffiles.begin(); fit!=freffiles.end(); fit++) {
01063     toccmd+= " " + *fit;
01064   }
01065   toccmd=mFaudesBinRef2html + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -toc " + toccmd
01066     + " " + mFaudesDocToc;
01067   std::cerr << "flxinstall: creating toc" << std::endl;
01068   //std::cerr << "flxinstall: creating toc from " << toccmd << std::endl;
01069   if(std::system(toccmd.c_str())!=0) {
01070     std::cerr << "flxinstall: error setting up toc: ERROR." << std::endl;
01071     exit(1);
01072   }
01073   std::cerr << "flxinstall: creating toc: done" << std::endl;
01074 
01075   // process all pages
01076   for(std::set < std::string >::iterator fit=freffiles.begin(); fit!=freffiles.end(); fit++) {
01077     // figure dest
01078     TokenReader tr(*fit);
01079     Token btag;
01080     tr.ReadBegin("ReferencePage",btag);
01081     std::string chapter;
01082     if(btag.ExistsAttributeString("chapter")) 
01083       chapter=btag.AttributeStringValue("chapter");
01084     std::string section;
01085     if(btag.ExistsAttributeString("section")) 
01086       section=btag.AttributeStringValue("section");
01087     std::string page;
01088     if(btag.ExistsAttributeString("page")) 
01089       page=btag.AttributeStringValue("page");
01090     // normalize & report 
01091     std::transform(chapter.begin(), chapter.end(), chapter.begin(), tolower);
01092     std::transform(section.begin(), section.end(), section.begin(), tolower);
01093     std::transform(page.begin(), page.end(), page.begin(), tolower);
01094     // insist in page,section and chapter (too strict .. many pages have no label)
01095     /*
01096     if(page=="" || section=="" || chapter=="") {
01097       std::cerr << "flxinstall: skipping undefined page \"" << *fit <<"\"" << std::endl;
01098       continue;
01099     } 
01100     */ 
01101     // figure destination
01102     std::string dstfile;   
01103     // dst: refernce
01104     if(chapter=="reference")
01105        dstfile=PrependDirectory(mFaudesDocRegistry,ExtractBasename(*fit) + ".html");
01106     // dst: luafaudes
01107     if(chapter=="luafaudes" && mFaudesDocLuafaudes!="") 
01108        dstfile=PrependDirectory(mFaudesDocLuafaudes,ExtractBasename(*fit) + ".html");
01109     // dst: unknown
01110     if(chapter!="reference" && chapter!="luafaudes") {
01111       std::cerr << "flxinstall: skipping out-of-scope page \"" << *fit <<"\"" << std::endl;
01112       continue;
01113     } 
01114     // set up command
01115     std::string proccmd= mFaudesBinRef2html 
01116        + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNavigation
01117        + " -css faudes.css " + " -inc " + mFaudesDocToc + " -rel ../  " 
01118       + *fit +  " " + dstfile;
01119     //std::cerr << "flxinstall: process " << proccmd << std::endl;
01120     std::cerr << "flxinstall: process \"" << *fit << "\"" << std::endl;
01121     if(std::system(proccmd.c_str())!=0) {
01122       std::cerr << "flxinstall: error when processing \"" << *fit << "\": ERROR." << std::endl;
01123       exit(1);
01124     }
01125   }
01126 
01127   // copy index file
01128   std::string dst=PrependDirectory(mFaudesDocRegistry,"index.html");
01129   std::string proccmd= mFaudesBinRef2html 
01130       + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNavigation
01131       + " -css faudes.css " + " -inc " + mFaudesDocToc + " -rel ../  " 
01132       + PrependDirectory(mFaudesDocRegistry,"corefaudes_index.fref") +  " " + dst;
01133   std::cerr << "flxinstall: fix html index " << std::endl;
01134   if(std::system(proccmd.c_str())!=0) {
01135     std::cerr << "flxinstall: error when processing index.html: ERROR." <<std::endl;
01136     exit(1);
01137   }
01138 
01139   // clean tmp
01140   /*
01141   for(std::set < std::string >::iterator fit=tmpfiles.begin(); fit!=tmpfiles.end(); fit++) {
01142     std::string dfile=PrependDirectory(mFaudesDocTemp,*fit);
01143     RemoveFile(*fit);
01144   }
01145   */
01146   std::cerr << "flxinstall: done" << std::endl;
01147   
01148 
01149   
01150 }
01151 
01152 
01153 // ******************************************************************
01154 // extract extension
01155 // ******************************************************************
01156 
01157 // control
01158 void ExtractExtensionFile(void) {
01159 
01160   // test extension
01161   std::string ext=ExtractExtension(mSourceFile);
01162   std::string bas=ExtractBasename(mSourceFile);
01163   if(ext!="flx") 
01164     usage_exit("extract must specify a .flx source");
01165   // prepare to read
01166   TokenReader tr(mSourceFile);
01167   Token btag;
01168   tr.ReadBegin("LuaExtension",btag);
01169   if(!btag.ExistsAttributeString("name")) {
01170     std::cerr << "flxinstall: lua-extension must have a name attribute " << tr.FileLine() << ": ERROR." << std::endl;
01171     exit(1);
01172   }
01173   mExtensionName=btag.AttributeStringValue("name");  
01174   // scan for relevant sections
01175   while(!tr.Eos("LuaExtension")) {
01176     tr.Peek(btag);
01177     // skip tokens
01178     if(!btag.IsBegin()) {
01179       tr.Get(btag);
01180       continue;
01181     }
01182     // switch sections: fref
01183     if(btag.StringValue()=="ReferencePage") {
01184       // figure destination
01185       if(!btag.ExistsAttributeString("page")) {
01186         std::cerr << "flxinstall: skipping referencepage without page attribute" << std::endl;
01187         tr.ReadBegin(btag.StringValue());
01188         tr.ReadEnd(btag.StringValue());
01189         continue;
01190       }
01191       std::string page=mExtensionName + "_" + btag.AttributeStringValue("page") +".fref";
01192       std::transform(page.begin(), page.end(), page.begin(), tolower);
01193       std::string dstname= mTarget + DirSeparator() + page;
01194       std::cerr << "flxinstall: extracting reference page to \"" << dstname << "\"" << std::endl;
01195       // do copy
01196       TokenWriter tw(dstname,"ReferencePage");
01197       InsertReferencePage(tr,tw,mExtensionName);
01198       continue;
01199     }
01200     // switch sections: lua function
01201     if(btag.StringValue()=="LuaFunctionDefinition") {
01202       // figure destination
01203       if(!btag.ExistsAttributeString("name")) { 
01204         std::cerr << "flxinstall: skipping lua function without name attribute" << std::endl;
01205         tr.ReadBegin(btag.StringValue());
01206         tr.ReadEnd(btag.StringValue());
01207         continue;
01208       }
01209       std::string name=btag.AttributeStringValue("name");
01210       size_t pos=name.find("::"); // test this construct for "xyz::"
01211       if(pos!=std::string::npos) name=name.substr(pos+2);
01212       name = name +".rti";
01213       std::transform(name.begin(), name.end(), name.begin(), tolower);
01214       std::string dstname= mTarget + DirSeparator() + name;
01215       std::cerr << "flxinstall: extracting lua function to \"" << dstname << "\"" << std::endl;
01216       // do copy
01217       TokenWriter tw(dstname,"LuaFunctionDefinition");
01218       InsertLuaFunction(tr,tw);
01219       continue;
01220     }
01221     // switch sections: image file
01222     if(btag.StringValue()=="ImageFile") {
01223       // figure destination
01224       if(!btag.ExistsAttributeString("name")) { 
01225         std::cerr << "flxinstall: skipping image file without name attribute" << std::endl;
01226         tr.ReadBegin(btag.StringValue());
01227         tr.ReadEnd(btag.StringValue());
01228         continue;
01229       }
01230       std::string name= btag.AttributeStringValue("name");
01231       std::transform(name.begin(), name.end(), name.begin(), tolower);
01232       std::string dstname= mTarget + DirSeparator() + name;
01233       std::cerr << "flxinstall: extracting image file to \"" << dstname << "\"" << std::endl;
01234       TokenWriter tw(dstname);
01235       // read data
01236       tr.ReadBegin("ImageFile");
01237       Token data;
01238       tr.Get(data);
01239       if(!data.IsBinary()){
01240       }
01241       // copy to C++ stream
01242       std::fstream fsout;
01243       fsout.exceptions(std::ios::badbit|std::ios::failbit);
01244       try{
01245         fsout.open(dstname.c_str(), std::ios::out | std::ios::binary); 
01246         fsout.write(data.StringValue().c_str(),data.StringValue().size());
01247         fsout.close();
01248       } 
01249       catch (std::ios::failure&) {
01250         std::cerr << "flxinstall: file io error when writing  \"" << dstname << "\"" << std::endl;
01251       }
01252       // done
01253       tr.ReadEnd("ImageFile");
01254       continue;
01255     }
01256     // switch sections: data file
01257     if(btag.StringValue()=="DataFile") {
01258       // figure destination
01259       if(!btag.ExistsAttributeString("name")) { 
01260         std::cerr << "flxinstall: skipping data file without name attribute" << std::endl;
01261         tr.ReadBegin(btag.StringValue());
01262         tr.ReadEnd(btag.StringValue());
01263         continue;
01264       }
01265       std::string name= "data" + DirSeparator() + btag.AttributeStringValue("name");
01266       std::transform(name.begin(), name.end(), name.begin(), tolower);
01267       std::string dstname= mTarget + DirSeparator() + name;
01268       std::cerr << "flxinstall: extracting data file to \"" << dstname << "\"" << std::endl;
01269       // insist in data directiory
01270       MakeDirectory(mTarget,"data");
01271       TokenWriter tw(dstname);
01272       // read data
01273       tr.ReadBegin("DataFile");
01274       Token data;
01275       tr.Peek(data);
01276       // case 1: binary
01277       if(data.IsBinary()){
01278         tr.Get(data);
01279         // copy to C++ stream
01280         std::fstream fsout;
01281         fsout.exceptions(std::ios::badbit|std::ios::failbit);
01282         try{
01283           fsout.open(dstname.c_str(), std::ios::out | std::ios::binary); 
01284           fsout.write(data.StringValue().c_str(),data.StringValue().size());
01285           fsout.close();
01286         } catch (std::ios::failure&) {
01287           std::cerr << "flxinstall: file io error when writing  \"" << dstname << "\"" << std::endl;
01288         }
01289       }
01290       // case 2: token stream
01291       else if(data.IsBegin()){
01292         // copy to token writer
01293         InsertSection(tr,tw,data.StringValue());
01294       }
01295       // case 3: error
01296       else {
01297         std::cerr << "flxinstall: skipping invalid data " << tr.FileLine() << std::endl;
01298       } 
01299       // read end tag
01300       tr.ReadEnd("DataFile");
01301       continue;
01302     }
01303     // switch sections: data file
01304     if(btag.StringValue()=="LuaTutorial") {
01305       // figure destination
01306       if(!btag.ExistsAttributeString("name")) { 
01307         std::cerr << "flxinstall: skipping tutorial without name attribute" << std::endl;
01308         tr.ReadBegin(btag.StringValue());
01309         tr.ReadEnd(btag.StringValue());
01310         continue;
01311       }
01312       std::string name=btag.AttributeStringValue("name");
01313       std::transform(name.begin(), name.end(), name.begin(), tolower);
01314       std::string dstname= mTarget + DirSeparator() + name;
01315       std::cerr << "flxinstall: extracting tutorial to \"" << dstname << "\"" << std::endl;
01316       // do copy
01317       TokenWriter tw(dstname);
01318       InsertPlainLuaTutorial(tr,tw);
01319       continue;
01320     }
01321     // skip unknown
01322     tr.ReadBegin(btag.StringValue());
01323     tr.ReadEnd(btag.StringValue());
01324   }
01325   // done
01326   tr.ReadEnd("LuaExtension");
01327 }
01328 
01329 
01330 
01331 // ******************************************************************
01332 // command line ui
01333 // ******************************************************************
01334 
01335 
01336 int main(int argc, char *argv[]) {
01337 
01338   // local config 
01339   bool doc=false;
01340   bool doi=false;
01341   bool dor=false;
01342   bool dox=false;
01343 
01344   // min args
01345   if(argc < 2) usage_exit();
01346 
01347   // primitive commad line parsing
01348   int i;
01349   for(i=1; i<argc; i++) {
01350     std::string option(argv[i]);
01351     // overwrite doc
01352     if(option=="-tdoc") { 
01353       i++; if(i>=argc) usage_exit();
01354       mFaudesDoc=argv[i];
01355       continue;
01356     }
01357     // overwrite bin
01358     if(option=="-tbin") { 
01359       i++; if(i>=argc) usage_exit();
01360       mFaudesBin=argv[i];
01361       continue;
01362     }
01363     // overwrite rti
01364     if(option=="-trti") { 
01365       i++; if(i>=argc) usage_exit();
01366       mFaudesDocRti=argv[i];
01367       continue;
01368     }
01369     // overwrite cnav
01370     if(option=="-tcnav") { 
01371       i++; if(i>=argc) usage_exit();
01372       mFaudesDocNavigation=argv[i];
01373       continue;
01374     }
01375     // overwrite css
01376     if(option=="-tcss") { 
01377       i++; if(i>=argc) usage_exit();
01378       mFaudesDocCss=argv[i];
01379       continue;
01380     }
01381     // mode: compile
01382     if(option=="-c") { 
01383       i++; doc=true;
01384       break;
01385     }
01386     // mode: install
01387     if(option=="-i") { 
01388       i++; doi=true;
01389       break;
01390     }
01391     // mode: remove
01392     if(option=="-r") { 
01393       i++; dor=true;
01394       break;
01395     }
01396     // mode: extract
01397     if(option=="-x") { 
01398       i++; dox=true;
01399       break;
01400     }
01401     // option: help
01402     if((option=="-?") || (option=="--help")) {
01403       usage_exit();
01404       continue;
01405     }
01406     // option: unknown
01407     if(option.size()>1)
01408     if(option.at(0)=='-') {
01409       usage_exit("unknown option " + option);
01410       continue;
01411     }
01412     // must choose mode
01413     usage_exit("must use either -c, -r or -i option" );
01414   }
01415 
01416   // create
01417   if(doc) {
01418     // figure source files 
01419     for(;i<argc-1;i++) {
01420       mSourceFiles.insert(std::string(argv[i]));
01421     }
01422     // convenience: if its a directory, use all files inside
01423     if(mSourceFiles.size()==1) {
01424       std::set< std::string > srcfiles = ReadDirectory(std::string(argv[i-1]));
01425       srcfiles=EraseHiddenFiles(srcfiles);
01426       if(srcfiles.size()>0) {
01427         mSourceFiles.clear();
01428         for(std::set < std::string >::iterator fit=srcfiles.begin(); fit!=srcfiles.end(); fit++) 
01429           mSourceFiles.insert(PrependDirectory(std::string(argv[i-1]),*fit));
01430       }
01431     }
01432     // convenience: all of current dir
01433     if(mSourceFiles.empty()) {
01434       mSourceFiles=ReadDirectory(".");
01435       mSourceFiles=EraseHiddenFiles(mSourceFiles);
01436     }
01437     // have a target file
01438     if(!(i<argc))
01439       usage_exit("target *.flx-file not specified");
01440     //  figure target file
01441     mTarget=std::string(argv[i]);
01442     // consistency: insist in .flx target
01443     if(mTarget!="-")
01444     if(ExtractExtension(mTarget)!="flx") 
01445       usage_exit("target *.flx-file not specified");
01446     // doit
01447     CreateExtensionFile();
01448     exit(0);
01449   }
01450 
01451   // install
01452   if(doi) {
01453     // figure scource files
01454     for(;i<argc-1;i++) {
01455       mSourceFiles.insert(std::string(argv[i]));
01456     }
01457     // have at least one file
01458     if(!(i<argc)) {
01459       usage_exit("target not specified");
01460     }
01461     // figure target file
01462     mTarget=std::string(argv[i]);
01463     TestFaudesTarget();
01464     // convenience: if exactly one file is specified with no extension,
01465     // interpret this as a directory
01466     if(mSourceFiles.size()==1) 
01467     if(ExtractExtension(*mSourceFiles.begin())!="flx") {
01468       std::string sdir=*mSourceFiles.begin();
01469       mSourceFiles=ReadDirectory(sdir);
01470       mSourceFiles=EraseHiddenFiles(mSourceFiles);
01471     }
01472     // doit
01473     InstallExtensionFiles();
01474     exit(0);
01475   }
01476 
01477   // xtract
01478   if(dox) {
01479     // figure source
01480     if(!(i<argc))
01481       usage_exit("source not specified");
01482     mSourceFile=std::string(argv[i++]);
01483     // destination
01484     if(!(i<argc))
01485       usage_exit("target not specified");
01486     mTarget=std::string(argv[i++]);
01487     // test consistent args
01488     if((i<argc))
01489       usage_exit("too many arguments");
01490     // doit
01491     MakeDirectory(".",mTarget);
01492     ExtractExtensionFile();
01493     exit(0);
01494   }
01495 
01496   // remove
01497   if(dor) {
01498     // have at least one file
01499     if(i!=argc-1)
01500       usage_exit("target not specified");
01501     //  figure target file
01502     mTarget=std::string(argv[i]);
01503     TestFaudesTarget();
01504     // doit
01505     InstallExtensionFiles();
01506     exit(0);
01507   }
01508 
01509   // error
01510   usage_exit();
01511   exit(1);
01512 }

libFAUDES 2.20s --- 2011.10.12 --- c++ source docu by doxygen