flxinstall.cppGo 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: " << VersionString() << 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 <other options> <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 << " -t extract and test extension (*.flx file) to output directory" << std::endl; 00058 std::cerr << std::endl; 00059 std::cerr << "note: <other options> address the default target layout" << std::endl; 00060 exit(1); 00061 } 00062 00063 00064 // ****************************************************************** 00065 // Configuration 00066 // ****************************************************************** 00067 00068 00069 std::string mXmlSeparator = "<!-- ================================================================================ -->"; 00070 00071 00072 // source/contents/detination 00073 std::set < std::string > mSourceFiles; 00074 std::string mSourceFile; 00075 std::string mTarget; 00076 std::string mExtensionName; 00077 std::set < std::string > mReferencePages; 00078 std::set < std::string > mGeneratorFiles; 00079 std::set < std::string > mImageFiles; 00080 std::set < std::string > mLuaFunctions; 00081 00082 00083 // destination layout (effective, defaults to libfaudes std) 00084 std::string mFaudesBase; 00085 std::string mFaudesBin; 00086 std::string mFaudesBinLuafaudes; 00087 std::string mFaudesBinLuaflx; 00088 std::string mFaudesBinRef2html; 00089 bool mFaudesStandalone = false; 00090 std::string mFaudesBinLua2ref; 00091 std::string mFaudesDoc; 00092 std::string mFaudesDocCss; 00093 std::string mFaudesDocToc; 00094 std::string mFaudesDocNav; 00095 std::string mFaudesDocRti; 00096 std::string mFaudesDocReference; 00097 std::string mFaudesDocLuafaudes; 00098 std::string mFaudesDocImages; 00099 std::string mFaudesDocRefsrc; 00100 std::string mFaudesDocTemp; 00101 00102 00103 00104 // ****************************************************************** 00105 // helper: make/remove dir 00106 // ****************************************************************** 00107 00108 // mkdir 00109 void MakeDirectory(const std::string& rPath, const std::string& rDir="") { 00110 std::string dir = rPath; 00111 if(rDir!="") dir += faudes_pathsep() + rDir; 00112 if(DirectoryExists(dir)) return; 00113 std::cerr << "flxinstall: creating dir \"" << dir << "\"" << std::endl; 00114 int sysret=std::system(std::string("mkdir " + dir).c_str()); 00115 if(sysret!=0) { 00116 std::cerr << "flxinstall: error while creating directory \"" << dir << "\"" << std::endl; 00117 usage_exit(); 00118 } 00119 } 00120 00121 00122 // remove unix hidden files from list 00123 std::set < std::string > EraseHiddenFiles(const std::set < std::string > & src) { 00124 std::set < std::string > res; 00125 for(std::set < std::string >::iterator fit=src.begin(); fit!=src.end(); fit++) { 00126 if(*fit=="") continue; 00127 if((*fit).at(0)=='.') continue; 00128 res.insert(*fit); 00129 } 00130 return res; 00131 } 00132 00133 00134 00135 // ****************************************************************** 00136 // helper: lua to ref process 00137 // ****************************************************************** 00138 00139 void Lua2ref(const std::string& rLuaFile, const std::string& rRefFile="") { 00140 // bail out 00141 if(mFaudesBinLua2ref=="") { 00142 std::cerr << "flxinstall: ignoring lua script \"" << rLuaFile << "\"" << std::endl; 00143 return; 00144 } 00145 // set up target 00146 std::string dst=rRefFile; 00147 if(dst=="") { 00148 dst=PrependDirectory(ExtractDirectory(rLuaFile),ExtractBasename(rLuaFile)+ ".fref"); 00149 } 00150 // set up command 00151 std::string cmd= mFaudesBinLua2ref + " " + rLuaFile + " > " + dst; 00152 // run 00153 std::cerr << "flxinstall: converting lua script \"" << rLuaFile << "\"" << std::endl; 00154 int sysret=std::system(cmd.c_str()); 00155 if(sysret!=0) { 00156 std::cerr << "flxinstall: error while converting lua script \"" << rLuaFile << "\"" << std::endl; 00157 usage_exit(); 00158 } 00159 00160 } 00161 00162 // ****************************************************************** 00163 // helper: gen to ref process 00164 // ****************************************************************** 00165 00166 void Gen2ref(const std::string& rGenFile, const std::string& rRefFile="") { 00167 std::cerr << "flxinstall: converting generator file \"" << rGenFile << "\"" << std::endl; 00168 std::string bas = ExtractBasename(rGenFile); 00169 // set up source and target 00170 std::string dst=rRefFile; 00171 if(dst=="") { 00172 dst=PrependDirectory(ExtractDirectory(rGenFile),bas+".fref"); 00173 } 00174 TokenWriter tw(dst); 00175 TokenReader tr(rGenFile); 00176 // convert 00177 try { 00178 // reference page 00179 Token btag; 00180 btag.SetBegin("ReferencePage"); 00181 btag.InsAttributeString("chapter","images"); 00182 btag.InsAttributeString("section","none"); 00183 btag.InsAttributeString("page","none"); 00184 btag.InsAttributeString("title","Example Data"); 00185 tw << btag; 00186 // headline 00187 tw.WriteCharacterData("<h1> Example Date: "+bas+".gen </h1>\n"); 00188 // svg image 00189 tw.WriteCharacterData("<h3> Dot-processed graph as SVG-image </h3>\n"); 00190 tw.WriteCharacterData("<object type=\"image/svg+xml\" name=\"graph\" data=\""+bas+".svg\">\n"); 00191 tw.WriteCharacterData("<a class=\"faudes_image\" href=\""+bas+".svg\">\n"); 00192 tw.WriteCharacterData("<img src=\"$genfile.png\" title=\"Click on image to download SVG formated file.\" />\n"); 00193 tw.WriteCharacterData("</a></object>"); 00194 // headline 00195 tw.WriteCharacterData("<h3>Token IO</h3>\n"); 00196 // copy generator 00197 tw.WriteBegin("pre"); 00198 const std::string& genstr=tr.ReadSection(); 00199 tw.WriteText(genstr); // this will escape critical entities 00200 tw.WriteEnd("pre"); 00201 // close my elements 00202 tw.WriteCharacterData("<p> </p><p> </p>\n"); 00203 tw.WriteEnd("ReferencePage"); 00204 } catch( faudes::Exception&){ 00205 std::cerr << "flxinstall: error while converting generator \"" << rGenFile << "\"" << std::endl; 00206 usage_exit(); 00207 } 00208 } 00209 00210 00211 // ****************************************************************** 00212 // helper: copy files 00213 // ****************************************************************** 00214 00215 // extract and copy token section 00216 void InsertSection(TokenReader& rTr, TokenWriter& rTw, const std::string& mLabel) { 00217 // get begin 00218 Token btag; 00219 rTr.ReadBegin(mLabel,btag); 00220 // copy section 00221 rTw.Write(btag); 00222 std::string scttext = rTr.ReadSection(); 00223 rTw.WriteCharacterData(scttext); 00224 rTw.WriteEnd(mLabel); 00225 // read end tag 00226 rTr.ReadEnd(mLabel); 00227 } 00228 00229 // extract and copy page data 00230 void InsertReferencePage(TokenReader& rTr, TokenWriter& rTw, const std::string mSection="") { 00231 // get begin 00232 Token btag; 00233 rTr.ReadBegin("ReferencePage",btag); 00234 // fix attributes 00235 if(!btag.ExistsAttributeString("chapter")) 00236 btag.InsAttributeString("chapter","Reference"); 00237 if(!btag.ExistsAttributeString("section")) 00238 if(mSection!="") 00239 btag.InsAttributeString("section",mSection); 00240 // copy section 00241 rTw.Write(btag); 00242 std::string scttext = rTr.ReadSection(); 00243 rTw.WriteCharacterData(scttext); 00244 rTw.WriteEnd("ReferencePage"); 00245 // read end tag 00246 rTr.ReadEnd("ReferencePage"); 00247 } 00248 00249 00250 // extract and copy luafunction 00251 void InsertLuaFunction(TokenReader& rTr, TokenWriter& rTw) { 00252 // get begin 00253 Token btag; 00254 rTr.ReadBegin("LuaFunctionDefinition",btag); 00255 // copy section 00256 rTw.Write(btag); 00257 std::string scttext = rTr.ReadSection(); 00258 rTw.WriteCharacterData(scttext); 00259 rTw.WriteEnd("LuaFunctionDefinition"); 00260 // read end tag 00261 rTr.ReadEnd("LuaFunctionDefinition"); 00262 } 00263 00264 00265 00266 // extract and copy tutorial (from xml to plain) 00267 void InsertPlainLuaTutorial(TokenReader& rTr, TokenWriter& rTw) { 00268 // get begin 00269 Token btag; 00270 rTr.ReadBegin("LuaTutorial",btag); 00271 // copy cdata 00272 std::string codestr; 00273 Token code; 00274 while(rTr.Peek(code)) { 00275 if(!code.IsString()) break; 00276 rTr.Get(code); 00277 codestr.append(code.StringValue()); 00278 } 00279 *rTw.Streamp() << codestr; 00280 // read end tag 00281 rTr.ReadEnd("LuaTutorial"); 00282 } 00283 00284 00285 // extract and copy tutorial (from plain to xml) 00286 void InsertLuaTutorial(TokenReader& rTr, TokenWriter& rTw) { 00287 // read script file to buffer 00288 char* buffer=0; 00289 long int size=0; 00290 try{ 00291 rTr.Rewind(); 00292 rTr.Streamp()->seekg(0, std::ios::end); 00293 std::streampos last = rTr.Streamp()->tellg(); 00294 rTr.Streamp()->seekg(0, std::ios::beg); 00295 std::streampos first = rTr.Streamp()->tellg(); 00296 size=(long int) last-first; 00297 buffer = new char[last-first]; 00298 rTr.Streamp()->read(buffer, last-first); 00299 rTr.Rewind(); 00300 } catch (std::ios::failure&) { 00301 std::cerr << "flxinstall: io error when reading \"" << rTr.FileName() << "\": ERROR." << std::endl; 00302 exit(1); 00303 } 00304 // convert (better solution?) 00305 std::string bufferstr; 00306 bufferstr.assign(buffer,size); 00307 // relative destination 00308 std::string name=rTr.FileName(); 00309 name=ExtractFilename(name); 00310 // write cdata encoded entry 00311 Token btag; 00312 btag.SetBegin("LuaTutorial"); 00313 btag.InsAttributeString("name",name); 00314 rTw.Write(btag); 00315 rTw.WriteVerbatim(bufferstr); 00316 rTw.WriteEnd("LuaTutorial"); 00317 // discard buffer 00318 delete buffer; 00319 } 00320 00321 00322 00323 // copy source as binary image file 00324 void InsertImageFile(TokenReader& rTr,TokenWriter& rTw) { 00325 // read image file to buffer 00326 char* buffer=0; 00327 long int size=0; 00328 try{ 00329 rTr.Rewind(); 00330 rTr.Streamp()->seekg(0, std::ios::end); 00331 std::streampos last = rTr.Streamp()->tellg(); 00332 rTr.Streamp()->seekg(0, std::ios::beg); 00333 std::streampos first = rTr.Streamp()->tellg(); 00334 size=(long int) last-first; 00335 buffer = new char[last-first]; 00336 rTr.Streamp()->read(buffer, last-first); 00337 rTr.Rewind(); 00338 } catch (std::ios::failure&) { 00339 std::cerr << "flxinstall: io error when reading \"" << rTr.FileName() << "\": ERROR." << std::endl; 00340 exit(1); 00341 } 00342 // relative destination 00343 std::string name=rTr.FileName(); 00344 name=ExtractFilename(name); 00345 // write Base64 encoded entry 00346 Token btag; 00347 btag.SetBegin("ImageFile"); 00348 btag.InsAttributeString("name",name); 00349 rTw.Write(btag); 00350 rTw.WriteBinary(buffer,size); 00351 rTw << "\n"; 00352 rTw.WriteEnd("ImageFile"); 00353 // discard buffer 00354 delete buffer; 00355 } 00356 00357 00358 00359 // copy source as binary data file 00360 void InsertDataFile(TokenReader& rTr,TokenWriter& rTw) { 00361 // read data file to buffer 00362 char* buffer=0; 00363 long int size=0; 00364 try{ 00365 rTr.Rewind(); 00366 rTr.Streamp()->seekg(0, std::ios::end); 00367 std::streampos last = rTr.Streamp()->tellg(); 00368 rTr.Streamp()->seekg(0, std::ios::beg); 00369 std::streampos first = rTr.Streamp()->tellg(); 00370 size=(long int) last-first; 00371 buffer = new char[last-first]; 00372 rTr.Streamp()->read(buffer, last-first); 00373 rTr.Rewind(); 00374 } catch (std::ios::failure&) { 00375 std::cerr << "flxinstall: io error when reading \"" << rTr.FileName() << "\": ERROR." << std::endl; 00376 exit(1); 00377 } 00378 // relative destination 00379 std::string name=rTr.FileName(); 00380 name=ExtractFilename(name); 00381 // write Base64 encoded entry 00382 Token btag; 00383 btag.SetBegin("DataFile"); 00384 btag.InsAttributeString("name",name); 00385 rTw.Write(btag); 00386 rTw.WriteBinary(buffer,size); 00387 rTw << "\n"; 00388 rTw.WriteEnd("DataFile"); 00389 // discard buffer 00390 delete buffer; 00391 } 00392 00393 00394 00395 00396 // ****************************************************************** 00397 // create 00398 // ****************************************************************** 00399 00400 00401 // control 00402 void CreateExtensionFile(void) { 00403 00404 // ************ pass 1: inspect sources 00405 00406 // traverse images 00407 for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) { 00408 // test extension 00409 std::string ext=ExtractExtension(*fit); 00410 std::string bas=ExtractBasename(*fit); 00411 std::string pbas=ExtractDirectory(*fit)+bas; 00412 // case: full generator image 00413 if( mSourceFiles.find(pbas + ".gen") != mSourceFiles.end()) 00414 if( mSourceFiles.find(pbas + ".svg") != mSourceFiles.end()) 00415 if( mSourceFiles.find(pbas + ".png") != mSourceFiles.end()) { 00416 if( mGeneratorFiles.find(pbas) == mGeneratorFiles.end()) { 00417 std::cerr << "flxinstall: scanning full generator image \"" << pbas << ".*\"" << std::endl; 00418 mGeneratorFiles.insert(pbas); 00419 } 00420 continue; 00421 } 00422 // skip non images 00423 if(! ((ext=="png") || (ext=="svg") || (ext=="jpeg") || (ext=="jpg") )) continue; 00424 // case: std image/binary 00425 std::cerr << "flxinstall: scanning image file \"" << *fit << "\"" << std::endl; 00426 mImageFiles.insert(*fit); 00427 } 00428 // traverse luafunctions 00429 for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) { 00430 // test extension 00431 std::string ext=ExtractExtension(*fit); 00432 std::string bas=ExtractBasename(*fit); 00433 // cases: luafunction 00434 if(ext=="rti" && mImageFiles.find(bas)==mImageFiles.end()) { 00435 std::cerr << "flxinstall: scanning luafunction \"" << *fit << "\"" << std::endl; 00436 TokenReader tr(*fit); 00437 Token btag; 00438 tr.ReadBegin("LuaFunctionDefinition",btag); 00439 if(!btag.ExistsAttributeString("name")) { 00440 std::cerr << "flxinstall: name not specified " << tr.FileLine() << ": ERROR." << std::endl; 00441 exit(1); 00442 } 00443 // extract name and space 00444 std::string name; 00445 std::string space; 00446 name=btag.AttributeStringValue("name"); 00447 size_t pos=name.find("::"); 00448 if(pos!=std::string::npos) { 00449 space=name.substr(0,pos); 00450 name=name.substr(pos+2); 00451 } 00452 // insist in matching space 00453 if(space!="" && mExtensionName!="" && space!=mExtensionName) { 00454 std::cerr << "flxinstall: namespace must match extension name" << tr.FileLine() << ": ERROR." << std::endl; 00455 exit(1); 00456 } 00457 mExtensionName=space; 00458 // done 00459 tr.ReadEnd("LuaFunctionDefinition"); 00460 } 00461 } 00462 // traverse ref pages 00463 for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) { 00464 // test extension 00465 std::string ext=ExtractExtension(*fit); 00466 std::string bas=ExtractBasename(*fit); 00467 // cases: reference page 00468 if(ext=="fref") { 00469 std::cerr << "flxinstall: scanning reference page \"" << *fit << "\"" << std::endl; 00470 TokenReader tr(*fit); 00471 Token btag; 00472 tr.ReadBegin("ReferencePage",btag); 00473 if(!btag.ExistsAttributeString("page")) { 00474 std::cerr << "flxinstall: page not specified " << tr.FileLine() << ": ERROR." << std::endl; 00475 exit(1); 00476 } 00477 if(!btag.ExistsAttributeString("title")) { 00478 std::cerr << "flxinstall: title not specified " << tr.FileLine() << std::endl; 00479 exit(1); 00480 } 00481 if(btag.ExistsAttributeString("chapter")) 00482 if(btag.AttributeStringValue("chapter")!="Reference") { 00483 std::cerr << "flxinstall: chapter must be \"Reference\" " << tr.FileLine() << ": ERROR." << std::endl; 00484 exit(1); 00485 } 00486 if(btag.ExistsAttributeString("section")) 00487 if(mExtensionName.size()==0) { 00488 mExtensionName=btag.AttributeStringValue("section"); 00489 } 00490 if(btag.ExistsAttributeString("section")) 00491 if(mExtensionName!=btag.AttributeStringValue("section")) { 00492 std::cerr << "flxinstall: section name \"" << mExtensionName << "\" expected " 00493 << tr.FileLine() << ": ERROR." << std::endl; 00494 exit(1); 00495 } 00496 std::string page=btag.AttributeStringValue("page"); 00497 std::transform(page.begin(), page.end(), page.begin(), tolower); 00498 // swallow page number 00499 std::string ppage=page; 00500 std::size_t upos = ppage.find_first_of("_"); 00501 std::size_t dpos = 0; 00502 for(; dpos < ppage.size();dpos++) 00503 if(!isdigit(ppage.at(dpos))) break; 00504 if(upos!=std::string::npos) 00505 if(upos==dpos) 00506 if(upos+1<ppage.size()) 00507 ppage=ppage.substr(upos+1,ppage.size()-upos-1); 00508 // record 00509 if(mReferencePages.find(ppage)!=mReferencePages.end()) { 00510 std::cerr << "flxinstall: double page label \"" << ppage << "\" " 00511 << tr.FileLine() << ": ERROR." << std::endl; 00512 exit(1); 00513 } 00514 mReferencePages.insert(ppage); 00515 tr.ReadEnd("ReferencePage"); 00516 } 00517 } 00518 if(mReferencePages.find("index")==mReferencePages.end()) { 00519 std::cerr << "flxinstall: missing index page, will be generated on installation." << std::endl; 00520 } 00521 00522 00523 // ************ pass 2: read/copy sources 00524 00525 // set up target 00526 TokenWriter* ptw=0; 00527 if(mTarget=="") { 00528 mTarget=mExtensionName + ".flx"; 00529 std::transform(mTarget.begin(), mTarget.end(), mTarget.begin(), tolower); 00530 } 00531 if(mTarget!="-") 00532 ptw=new TokenWriter(mTarget,"LuaExtension"); 00533 else 00534 ptw=new TokenWriter(TokenWriter::Stdout); 00535 // indicate tool version 00536 *ptw->Streamp() << "<!-- flxinstall " << VersionString() << " -->" << std::endl; 00537 // start tag 00538 Token btag; 00539 btag.SetBegin("LuaExtension"); 00540 btag.InsAttributeString("name",mExtensionName); 00541 ptw->Write(btag); 00542 // traverse files 00543 for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) { 00544 // test extension 00545 std::string ext=ExtractExtension(*fit); 00546 std::string bas=ExtractBasename(*fit); 00547 std::string pbas=ExtractDirectory(*fit)+bas; 00548 // cases: reference page 00549 if(ext=="fref") { 00550 std::cerr << "flxinstall: appending reference page from \"" << *fit << "\"" << std::endl; 00551 *ptw << "\n" << "\n"; 00552 *ptw->Streamp() << mXmlSeparator << std::endl; 00553 *ptw->Streamp() << mXmlSeparator << std::endl; 00554 *ptw->Streamp() << mXmlSeparator << std::endl; 00555 *ptw->Streamp() << "<!-- reference page from source \"" << *fit << "\" -->" << std::endl; 00556 *ptw << "\n" << "\n"; 00557 TokenReader tr(*fit); 00558 InsertReferencePage(tr,*ptw,mExtensionName); 00559 continue; 00560 } 00561 // cases: code 00562 if(ext=="rti") { 00563 std::cerr << "flxinstall: appending lua function from \"" << *fit << "\"" << std::endl; 00564 *ptw << "\n" << "\n"; 00565 *ptw->Streamp() << mXmlSeparator << std::endl; 00566 *ptw->Streamp() << mXmlSeparator << std::endl; 00567 *ptw->Streamp() << mXmlSeparator << std::endl; 00568 *ptw->Streamp() << "<!-- lua function from source \"" << *fit << "\" -->" << std::endl; 00569 *ptw << "\n" << "\n"; 00570 TokenReader tr(*fit); 00571 InsertLuaFunction(tr,*ptw); 00572 continue; 00573 } 00574 // cases: binary image 00575 if(mImageFiles.find(*fit)!=mImageFiles.end()) { 00576 std::cerr << "flxinstall: appending image/binary file from \"" << *fit << "\"" << std::endl; 00577 *ptw << "\n" << "\n"; 00578 *ptw->Streamp() << mXmlSeparator << std::endl; 00579 *ptw->Streamp() << mXmlSeparator << std::endl; 00580 *ptw->Streamp() << mXmlSeparator << std::endl; 00581 *ptw->Streamp() << "<!-- binary file from source \"" << *fit << "\" -->" << std::endl; 00582 *ptw << "\n" << "\n"; 00583 TokenReader tr(*fit); 00584 InsertImageFile(tr,*ptw); 00585 continue; 00586 } 00587 // cases: full generator image 00588 if(mGeneratorFiles.find(pbas)!=mGeneratorFiles.end()) { 00589 std::cerr << "flxinstall: appending full generator from \"" << pbas << ".*\"" << std::endl; 00590 *ptw << "\n" << "\n"; 00591 *ptw->Streamp() << mXmlSeparator << std::endl; 00592 *ptw->Streamp() << mXmlSeparator << std::endl; 00593 *ptw->Streamp() << mXmlSeparator << std::endl; 00594 *ptw->Streamp() << "<!-- full generator image from source \"" << pbas << ".*\" -->" << std::endl; 00595 *ptw << "\n" << "\n"; 00596 TokenReader trg(pbas+".gen"); 00597 InsertImageFile(trg,*ptw); 00598 *ptw << "\n" << "\n"; 00599 TokenReader trs(pbas+".svg"); 00600 InsertImageFile(trs,*ptw); 00601 *ptw << "\n" << "\n"; 00602 TokenReader trp(pbas+".png"); 00603 InsertImageFile(trp,*ptw); 00604 mGeneratorFiles.erase(pbas); 00605 continue; 00606 } 00607 // cases: tutorial 00608 if(ext=="lua") { 00609 std::cerr << "flxinstall: appending tutorial from \"" << *fit << "\"" << std::endl; 00610 *ptw << "\n" << "\n"; 00611 *ptw->Streamp() << mXmlSeparator << std::endl; 00612 *ptw->Streamp() << mXmlSeparator << std::endl; 00613 *ptw->Streamp() << mXmlSeparator << std::endl; 00614 *ptw->Streamp() << "<!-- tutorial from source \"" << *fit << "\" -->" << std::endl; 00615 *ptw << "\n" << "\n"; 00616 TokenReader tr(*fit); 00617 InsertLuaTutorial(tr,*ptw); 00618 continue; 00619 } 00620 // cases: data directory 00621 if(ext=="" && bas=="data") { 00622 std::set< std::string > datafiles = ReadDirectory(*fit); 00623 datafiles=EraseHiddenFiles(datafiles); 00624 if(datafiles.size()==0) continue; 00625 std::cerr << "flxinstall: appending data files \"" << *fit << "\"" << std::endl; 00626 *ptw << "\n" << "\n"; 00627 *ptw->Streamp() << mXmlSeparator << std::endl; 00628 *ptw->Streamp() << mXmlSeparator << std::endl; 00629 *ptw->Streamp() << mXmlSeparator << std::endl; 00630 *ptw->Streamp() << "<!-- data from source \"" << *fit << "\" -->" << std::endl; 00631 *ptw << "\n" << "\n"; 00632 std::set< std::string >::iterator dit; 00633 for(dit=datafiles.begin();dit!=datafiles.end();dit++) { 00634 std::string srcfile=PrependDirectory(*fit,*dit); 00635 TokenReader tr(srcfile); 00636 InsertDataFile(tr,*ptw); 00637 } 00638 } 00639 } 00640 // cleanup/close 00641 *ptw << "\n" << "\n"; 00642 ptw->WriteEnd("LuaExtension"); 00643 delete ptw; 00644 } 00645 00646 00647 // ****************************************************************** 00648 // test libfaudes installation 00649 // ****************************************************************** 00650 00651 // inspect libfaudes distribution to locate luafaudes (use mFaudesBin) 00652 void TestLuafaudes(void) { 00653 // read bin dir 00654 if(!DirectoryExists(mFaudesBin)){ 00655 std::cerr << "flxinstall: cannot open libfaudes binary path \"" << mFaudesBin << "\": ERROR." << std::endl; 00656 exit(1); 00657 } 00658 std::set< std::string > binfiles = ReadDirectory(mFaudesBin); 00659 // find luafaudes 00660 mFaudesBinLuafaudes=""; 00661 if(binfiles.find("luafaudes.exe")!= binfiles.end()) { 00662 mFaudesBinLuafaudes=PrependDirectory(mFaudesBin,"luafaudes.exe"); 00663 } 00664 if(binfiles.find("luafaudes")!= binfiles.end()) { 00665 mFaudesBinLuafaudes=PrependDirectory(mFaudesBin,"luafaudes"); 00666 } 00667 if(!FileExists(mFaudesBinLuafaudes)) { 00668 std::cerr << "flxinstall: warning: cannot open luafaudes in \"" << mFaudesBin << "\"" << std::endl; 00669 mFaudesBinLuafaudes=""; 00670 } 00671 } 00672 00673 // inspect libfaudes distribution 00674 void TestFaudesTarget(void) { 00675 mFaudesBase=mTarget; 00676 std::set< std::string > faudesfiles = ReadDirectory(mFaudesBase); 00677 // bad dir 00678 if(faudesfiles.empty()) { 00679 std::cerr << "flxinstall: cannot open target directory \"" << mFaudesBase << "\": ERROR." << std::endl; 00680 exit(1); 00681 } 00682 // bin (allow overwrite) 00683 if(mFaudesBin=="") { 00684 mFaudesBin=mFaudesBase; 00685 if(faudesfiles.find("bin")!= faudesfiles.end()) 00686 mFaudesBin=PrependDirectory(mFaudesBase,"bin"); 00687 } 00688 if(!DirectoryExists(mFaudesBin)){ 00689 std::cerr << "flxinstall: cannot open libfaudes binary path in \"" << mFaudesBin << "\": ERROR." << std::endl; 00690 exit(1); 00691 } 00692 std::set< std::string > binfiles = ReadDirectory(mFaudesBin); 00693 // insist in ref2html 00694 mFaudesBinRef2html=""; 00695 if(binfiles.find("ref2html.exe")!= binfiles.end()) { 00696 mFaudesBinRef2html=PrependDirectory(mFaudesBin,"ref2html.exe"); 00697 } 00698 if(binfiles.find("ref2html")!= binfiles.end()) { 00699 mFaudesBinRef2html=PrependDirectory(mFaudesBin,"ref2html"); 00700 } 00701 if(mFaudesBinRef2html=="") { 00702 std::cerr << "flxinstall: cannot open ref2html tool in \"" << mFaudesBin << "\": ERROR." << std::endl; 00703 exit(1); 00704 } 00705 // ref2html options 00706 if(mFaudesStandalone) mFaudesBinRef2html += " -app"; 00707 // find luafaudes 00708 TestLuafaudes(); 00709 // default flx 00710 mFaudesBinLuaflx=PrependDirectory(mFaudesBin,"luafaudes.flx"); 00711 // doc (allow overwrite) 00712 if(mFaudesDoc=="") { 00713 mFaudesDoc=mFaudesBase; 00714 if(faudesfiles.find("doc")!= faudesfiles.end()) { 00715 mFaudesDoc=PrependDirectory(mFaudesDoc,"doc"); 00716 } else if(faudesfiles.find("Doc")!= faudesfiles.end()) { 00717 mFaudesDoc=PrependDirectory(mFaudesDoc,"Doc"); 00718 } else if(faudesfiles.find("Documentation")!= faudesfiles.end()) { 00719 mFaudesDoc=PrependDirectory(mFaudesDoc,"Documentation"); 00720 } 00721 if(!DirectoryExists(mFaudesDoc)){ 00722 std::cerr << "flxinstall: cannot open libfaudes documentation path in \"" << mFaudesBase << "\": ERROR." << std::endl; 00723 exit(1); 00724 } 00725 } 00726 if(!DirectoryExists(mFaudesDoc)){ 00727 std::cerr << "flxinstall: cannot open libfaudes documentation path at \"" << mFaudesDoc << "\": ERROR." << std::endl; 00728 exit(1); 00729 } 00730 std::set< std::string > docfiles = ReadDirectory(mFaudesDoc); 00731 // css (allow overwrite) 00732 if(mFaudesDocCss=="") mFaudesDocCss="faudes.css"; 00733 mFaudesDocCss=ExtractFilename(mFaudesDocCss); // ignore directory 00734 // reference 00735 mFaudesDocReference=mFaudesDoc; 00736 if(docfiles.find("reference")!= docfiles.end()) { 00737 mFaudesDocReference=PrependDirectory(mFaudesDoc,"reference"); 00738 } else if(docfiles.find("Reference")!= faudesfiles.end()) { 00739 mFaudesDocReference=PrependDirectory(mFaudesDoc,"Reference"); 00740 } 00741 if(!DirectoryExists(mFaudesDocReference)){ 00742 std::cerr << "flxinstall: cannot open libfaudes reference path in \"" << mFaudesDoc << "\": ERROR." << std::endl; 00743 exit(1); 00744 } 00745 std::set< std::string > regfiles = ReadDirectory(mFaudesDocReference); 00746 // luafaudes doc (default: non-existent) 00747 mFaudesDocLuafaudes=""; 00748 if(docfiles.find("luafaudes")!= docfiles.end()) { 00749 mFaudesDocLuafaudes=PrependDirectory(mFaudesDoc,"luafaudes"); 00750 } else if(docfiles.find("Luafaudes")!= docfiles.end()) { 00751 mFaudesDocLuafaudes=PrependDirectory(mFaudesDoc,"Luafaudes"); 00752 } 00753 // lua2ref (try luafaudes on lua2ref.lua) 00754 if(mFaudesBinLuafaudes!="") { 00755 std::string script = mFaudesBase + faudes_pathsep() + "tools" + faudes_pathsep() 00756 + "lua2ref" + faudes_pathsep() + "lua2ref.lua"; 00757 mFaudesBinLua2ref=mFaudesBinLuafaudes + " " + script; 00758 if(!FileExists(script)) mFaudesBinLua2ref = ""; 00759 if(!FileExists(mFaudesBinLuafaudes)) mFaudesBinLua2ref = ""; 00760 } 00761 // lua2ref (try perl on lua2ref.pl) 00762 if(mFaudesBinLua2ref=="") { 00763 mFaudesBinLua2ref = mFaudesBase + faudes_pathsep() + "tools" + faudes_pathsep() 00764 + "lua2ref" + faudes_pathsep() + "lua2ref.pl"; 00765 if(!FileExists(mFaudesBinLua2ref)) mFaudesBinLua2ref = ""; 00766 } 00767 // images 00768 mFaudesDocImages=""; 00769 if(docfiles.find("images")!= docfiles.end()) { 00770 mFaudesDocImages=PrependDirectory(mFaudesDoc,"images"); 00771 } else { 00772 std::cerr << "flxinstall: cannot open images in \"" << mFaudesDoc << "\": ERROR." << std::endl; 00773 exit(1); 00774 } 00775 // refsrc 00776 mFaudesDocRefsrc=""; 00777 if(docfiles.find("refsrc")!= docfiles.end()) { 00778 mFaudesDocRefsrc=PrependDirectory(mFaudesDoc,"refsrc"); 00779 } else { 00780 std::cerr << "flxinstall: cannot open refsrc in \"" << mFaudesDoc << "\": ERROR." << std::endl; 00781 exit(1); 00782 } 00783 std::set< std::string > refsrcfiles = ReadDirectory(mFaudesDocRefsrc); 00784 // rti (allow overwrite) 00785 if(mFaudesDocRti=="") mFaudesDocRti = PrependDirectory(mFaudesDocRefsrc,"libfaudes.rti"); 00786 if(!FileExists(mFaudesDocRti)){ 00787 std::cerr << "flxinstall: cannot open libfaudes.rti at \"" << mFaudesDocRti << "\": ERROR." << std::endl; 00788 exit(1); 00789 } 00790 // cnav (allow overwrite) 00791 if(mFaudesDocNav=="") mFaudesDocNav="faudes_navigation.include_fref"; 00792 mFaudesDocNav=ExtractFilename(mFaudesDocNav); // ignore directory 00793 mFaudesDocNav=PrependDirectory(mFaudesDocRefsrc,mFaudesDocNav); // enforce directory 00794 if(!FileExists(mFaudesDocNav)){ 00795 std::cerr << "flxinstall: cannot open navigation file \"" << mFaudesDocNav << "\": ERROR." << std::endl; 00796 exit(1); 00797 } 00798 // temp 00799 mFaudesDocTemp=PrependDirectory(mFaudesDocRefsrc,"tmp_flx"); 00800 if(docfiles.find("tmp_flx")== docfiles.end()) { 00801 std::cerr << "flxinstall: creating temp dir \"" << mFaudesDocTemp << "\"" << std::endl; 00802 MakeDirectory(mFaudesDocTemp); 00803 } 00804 mFaudesDocToc=PrependDirectory(mFaudesDocTemp,"toc.ftoc"); 00805 } 00806 00807 00808 // ****************************************************************** 00809 // extract reference pages 00810 // ****************************************************************** 00811 00812 00813 void XtractReferencePages(TokenReader& rTr, const std::string& rDstDir) { 00814 // read outer tag 00815 Token btag; 00816 rTr.Rewind(); 00817 rTr.ReadBegin("LuaExtension",btag); 00818 if(!btag.ExistsAttributeString("name")) { 00819 std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl; 00820 exit(1); 00821 } 00822 mExtensionName=btag.AttributeStringValue("name"); 00823 // scan for reference page sections 00824 while(!rTr.Eos("LuaExtension")) { 00825 rTr.Peek(btag); 00826 // skip tokens 00827 if(!btag.IsBegin()) { 00828 rTr.Get(btag); 00829 continue; 00830 } 00831 // skip sections 00832 if(btag.StringValue()!="ReferencePage") { 00833 rTr.ReadBegin(btag.StringValue()); 00834 rTr.ReadEnd(btag.StringValue()); 00835 continue; 00836 } 00837 // extract title & friends 00838 std::string title="libFAUDES Reference"; 00839 if(btag.ExistsAttributeString("title")) 00840 title=btag.AttributeStringValue("title"); 00841 std::string chapter="Reference"; 00842 if(btag.ExistsAttributeString("chapter")) 00843 chapter=btag.AttributeStringValue("chapter"); 00844 std::string section=""; 00845 if(btag.ExistsAttributeString("section")) 00846 section=btag.AttributeStringValue("section"); 00847 std::string page=""; 00848 if(btag.ExistsAttributeString("page")) 00849 page=btag.AttributeStringValue("page"); 00850 // insist in page and section 00851 if(page=="" || section=="") { 00852 std::cerr << "flxinstall: skipping undefined page at " << rTr.FileLine() << std::endl; 00853 rTr.ReadBegin("ReferencePage",btag); 00854 rTr.ReadEnd("ReferencePage"); 00855 continue; 00856 } 00857 // normalize & report 00858 std::transform(section.begin(), section.end(), section.begin(), tolower); 00859 std::transform(page.begin(), page.end(), page.begin(), tolower); 00860 // swallow page number 00861 std::string ppage=page; 00862 std::size_t upos = ppage.find_first_of("_"); 00863 std::size_t dpos = 0; 00864 for(; dpos < ppage.size();dpos++) 00865 if(!isdigit(ppage.at(dpos))) break; 00866 if(upos!=std::string::npos) 00867 if(upos==dpos) 00868 if(upos+1<ppage.size()) 00869 ppage=ppage.substr(upos+1,ppage.size()-upos-1); 00870 // basename 00871 std::string basename= section + "_" + ppage; 00872 mReferencePages.insert(basename); 00873 // dst file 00874 std::string dstfile=rDstDir + faudes_pathsep() + basename + ".fref"; 00875 std::cerr << "flxinstall: extracting reference page to \"" << dstfile << "\"" << std::endl; 00876 TokenWriter dst(dstfile); 00877 InsertReferencePage(rTr,dst); 00878 } 00879 } 00880 00881 // ****************************************************************** 00882 // extract image files 00883 // ****************************************************************** 00884 00885 00886 void XtractImageFiles(TokenReader& rTr,const std::string& rDstDir) { 00887 // read outer tag 00888 Token btag; 00889 rTr.Rewind(); 00890 rTr.ReadBegin("LuaExtension",btag); 00891 if(!btag.ExistsAttributeString("name")) { 00892 std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl; 00893 exit(1); 00894 } 00895 mExtensionName=btag.AttributeStringValue("name"); 00896 // scan for image files 00897 while(!rTr.Eos("LuaExtension")) { 00898 rTr.Peek(btag); 00899 // skip tokens 00900 if(!btag.IsBegin()) { 00901 rTr.Get(btag); 00902 continue; 00903 } 00904 // skip sections 00905 if(btag.StringValue()!="ImageFile") { 00906 rTr.ReadBegin(btag.StringValue()); 00907 rTr.ReadEnd(btag.StringValue()); 00908 continue; 00909 } 00910 // read begin tag 00911 rTr.ReadBegin("ImageFile",btag); 00912 std::string name=btag.AttributeStringValue("name"); 00913 if(name==""){ 00914 std::cerr << "flxinstall: image file must specify name " << rTr.FileLine() << std::endl; 00915 rTr.ReadEnd("ImageFile"); 00916 continue; 00917 } 00918 // skip non-image formats 00919 std::string ext = ExtractExtension(name); 00920 if(ext!="png" && ext!="svg" && ext!="jpg" && ext!="jpeg") { 00921 rTr.ReadEnd("ImageFile"); 00922 continue; 00923 } 00924 // read data 00925 Token data; 00926 rTr.Get(data); 00927 if(!data.IsBinary()){ 00928 std::cerr << "flxinstall: skipping invalid image data " << rTr.FileLine() << std::endl; 00929 rTr.ReadEnd("ImageFile"); 00930 continue; 00931 } 00932 // dst file 00933 std::transform(name.begin(), name.end(), name.begin(), tolower); 00934 std::string dstfile=rDstDir + faudes_pathsep() + name; 00935 std::cerr << "flxinstall: extracting image to \"" << dstfile << "\"" << std::endl; 00936 // record 00937 mImageFiles.insert(dstfile); 00938 // setup stream 00939 std::fstream fsout; 00940 fsout.exceptions(std::ios::badbit|std::ios::failbit); 00941 try{ 00942 fsout.open(dstfile.c_str(), std::ios::out | std::ios::binary); 00943 fsout.write(data.StringValue().c_str(),data.StringValue().size()); 00944 fsout.close(); 00945 } 00946 catch (std::ios::failure&) { 00947 std::cerr << "flxinstall: file io error when writing \"" << dstfile << "\"" << std::endl; 00948 } 00949 // read end tag 00950 rTr.ReadEnd("ImageFile"); 00951 } 00952 } 00953 00954 void XtractImageGenFiles(TokenReader& rTr,const std::string& rDstDir) { 00955 // read outer tag 00956 Token btag; 00957 rTr.Rewind(); 00958 rTr.ReadBegin("LuaExtension",btag); 00959 if(!btag.ExistsAttributeString("name")) { 00960 std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl; 00961 exit(1); 00962 } 00963 mExtensionName=btag.AttributeStringValue("name"); 00964 // scan for image files 00965 while(!rTr.Eos("LuaExtension")) { 00966 rTr.Peek(btag); 00967 // skip tokens 00968 if(!btag.IsBegin()) { 00969 rTr.Get(btag); 00970 continue; 00971 } 00972 // skip sections 00973 if(btag.StringValue()!="ImageFile") { 00974 rTr.ReadBegin(btag.StringValue()); 00975 rTr.ReadEnd(btag.StringValue()); 00976 continue; 00977 } 00978 // read begin tag 00979 rTr.ReadBegin("ImageFile",btag); 00980 std::string name=btag.AttributeStringValue("name"); 00981 if(name==""){ 00982 std::cerr << "flxinstall: image file must specify name " << rTr.FileLine() << std::endl; 00983 rTr.ReadEnd("ImageFile"); 00984 continue; 00985 } 00986 // skip non-gen formats 00987 std::string ext = ExtractExtension(name); 00988 if(ext!="gen"){ 00989 rTr.ReadEnd("ImageFile"); 00990 continue; 00991 } 00992 // read data 00993 Token data; 00994 rTr.Get(data); 00995 if(!data.IsBinary()){ 00996 std::cerr << "flxinstall: skipping invalid image data " << rTr.FileLine() << std::endl; 00997 rTr.ReadEnd("ImageFile"); 00998 continue; 00999 } 01000 // dst file 01001 std::transform(name.begin(), name.end(), name.begin(), tolower); 01002 std::string dstfile=rDstDir + faudes_pathsep() + name; 01003 std::cerr << "flxinstall: extracting image to \"" << dstfile << "\"" << std::endl; 01004 // record 01005 mImageFiles.insert(dstfile); 01006 // setup stream 01007 std::fstream fsout; 01008 fsout.exceptions(std::ios::badbit|std::ios::failbit); 01009 try{ 01010 fsout.open(dstfile.c_str(), std::ios::out | std::ios::binary); 01011 fsout.write(data.StringValue().c_str(),data.StringValue().size()); 01012 fsout.close(); 01013 } 01014 catch (std::ios::failure&) { 01015 std::cerr << "flxinstall: file io error when writing \"" << dstfile << "\"" << std::endl; 01016 } 01017 // read end tag 01018 rTr.ReadEnd("ImageFile"); 01019 } 01020 } 01021 01022 01023 // ****************************************************************** 01024 // extract lua code 01025 // ****************************************************************** 01026 01027 01028 01029 void XtractLuaFunctions(TokenReader& rTr, TokenWriter& rTw) { 01030 // read outer tag 01031 Token btag; 01032 rTr.Rewind(); 01033 rTr.ReadBegin("LuaExtension",btag); 01034 if(!btag.ExistsAttributeString("name")) { 01035 std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl; 01036 exit(1); 01037 } 01038 mExtensionName=btag.AttributeStringValue("name"); 01039 // scan for reference page sections 01040 while(!rTr.Eos("LuaExtension")) { 01041 rTr.Peek(btag); 01042 // skip tokens 01043 if(!btag.IsBegin()) { 01044 rTr.Get(btag); 01045 continue; 01046 } 01047 // skip sections 01048 if(btag.StringValue()!="LuaFunctionDefinition") { 01049 rTr.ReadBegin(btag.StringValue()); 01050 rTr.ReadEnd(btag.StringValue()); 01051 continue; 01052 } 01053 // extract title & friends 01054 std::string name; 01055 std::string space; 01056 if(btag.ExistsAttributeString("name")){ 01057 name=btag.AttributeStringValue("name"); 01058 size_t pos=name.find("::"); 01059 if(pos!=std::string::npos) { 01060 space=name.substr(0,pos); 01061 name=name.substr(pos+2); 01062 } 01063 } 01064 // insist in name 01065 if(name=="") { 01066 std::cerr << "flxinstall: skipping undefined lua function at " << rTr.FileLine() << std::endl; 01067 rTr.ReadBegin("LuaFunctionDefinition",btag); 01068 rTr.ReadEnd("LuafunctionDefinition"); 01069 continue; 01070 } 01071 // insist in space to match 01072 /* 01073 if(space!=mExtensionName) { 01074 std::cerr << "flxinstall: skipping undefined lua function at " << rTr.FileLine() << std::endl; 01075 rTr.ReadBegin("LuaFunctionDefinition",btag); 01076 rTr.ReadEnd("LuafunctionDefinition"); 01077 continue; 01078 } 01079 */ 01080 // record 01081 mLuaFunctions.insert(name); 01082 // copy 01083 std::cerr << "flxinstall: extracting lua function \"" << name << "\"" << std::endl; 01084 *rTw.Streamp() << mXmlSeparator << std::endl; 01085 *rTw.Streamp() << mXmlSeparator << std::endl; 01086 *rTw.Streamp() << "<!-- lua function from lua-extension " << rTr.FileLine() << " -->" << std::endl; 01087 rTw << "\n" << "\n"; 01088 InsertLuaFunction(rTr,rTw); 01089 } 01090 } 01091 01092 // ****************************************************************** 01093 // extract lua tutorials 01094 // ****************************************************************** 01095 01096 void XtractLuaTutorials(TokenReader& rTr, const std::string& rDstDir) { 01097 // read outer tag 01098 Token btag; 01099 rTr.Rewind(); 01100 rTr.ReadBegin("LuaExtension",btag); 01101 if(!btag.ExistsAttributeString("name")) { 01102 std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl; 01103 exit(1); 01104 } 01105 mExtensionName=btag.AttributeStringValue("name"); 01106 // scan for reference page sections 01107 while(!rTr.Eos("LuaExtension")) { 01108 rTr.Peek(btag); 01109 // skip tokens 01110 if(!btag.IsBegin()) { 01111 rTr.Get(btag); 01112 continue; 01113 } 01114 // skip sections 01115 if(btag.StringValue()!="LuaTutorial") { 01116 rTr.ReadBegin(btag.StringValue()); 01117 rTr.ReadEnd(btag.StringValue()); 01118 continue; 01119 } 01120 // test for name 01121 std::string name=btag.AttributeStringValue("name"); 01122 if(name==""){ 01123 std::cerr << "flxinstall: lua tutorial must specify name " << rTr.FileLine() << std::endl; 01124 rTr.ReadEnd("LuaTutorial"); 01125 continue; 01126 } 01127 // set up destination and copy 01128 std::transform(name.begin(), name.end(), name.begin(), tolower); 01129 std::string dstfile=rDstDir + faudes_pathsep() + name; 01130 std::cerr << "flxinstall: extracting lua tutorial to \"" << dstfile << "\"" << std::endl; 01131 TokenWriter tw(dstfile); 01132 InsertPlainLuaTutorial(rTr,tw); 01133 } 01134 } 01135 01136 // ****************************************************************** 01137 // generate default reference page 01138 // ****************************************************************** 01139 01140 void DefaultIndexPage(const std::string& rDstDir) { 01141 // name of index files 01142 std::string index=mExtensionName + "_index"; 01143 std::transform(index.begin(), index.end(), index.begin(), tolower); 01144 // test existence 01145 if(mReferencePages.find(index)!=mReferencePages.end()) { 01146 std::cerr << "flxinstall: index page provided" << std::endl; 01147 return; 01148 } 01149 // error case 01150 if(mReferencePages.size()>0) { 01151 std::cerr << "flxinstall: reference page missing: \"" << index << ".fref\": ERROR" << std::endl; 01152 exit(1); 01153 } 01154 // generates defaultindex page 01155 std::cerr << "flxinstall: generate index page" << std::endl; 01156 TokenWriter tw(rDstDir + faudes_pathsep() + index + ".fref","ReferencePage"); 01157 *tw.Streamp() << "<!-- flxinstall " << VersionString() << ": auto generated index -->" << std::endl; 01158 *tw.Streamp() << "<ReferencePage chapter=\"Reference\" section=\"" << mExtensionName << 01159 "\" page=\"0_Index\" title=\""<< mExtensionName << " Index\" >" << std::endl; 01160 // headline 01161 *tw.Streamp() << "<h1> " << mExtensionName << ": Functions </h1>" << std::endl; 01162 // list functions 01163 std::set< std::string >::iterator fit; 01164 for(fit=mLuaFunctions.begin(); fit!= mLuaFunctions.end(); fit++) { 01165 *tw.Streamp() << "<ffnct_reference name=\"" << *fit << "\" />" << std::endl; 01166 } 01167 // done 01168 *tw.Streamp() << "</ReferencePage>" << std::endl; 01169 } 01170 01171 01172 01173 01174 // ****************************************************************** 01175 // install extension 01176 // ****************************************************************** 01177 01178 // control 01179 void InstallExtensionFiles(void) { 01180 01181 // clear context 01182 mImageFiles.clear(); 01183 01184 // clean tmp (this is for dstinstall to see only relevant files in the temp directory) 01185 std::set< std::string > tmpfiles = ReadDirectory(mFaudesDocTemp); 01186 for(std::set < std::string >::iterator fit=tmpfiles.begin(); fit!=tmpfiles.end(); fit++) { 01187 std::string dfile=PrependDirectory(mFaudesDocTemp,*fit); 01188 if(!RemoveFile(dfile)) { 01189 std::cerr << "flxinstall: failed to remove \"" << *fit << "\"" << std::endl; 01190 }; 01191 } 01192 01193 // prepare luafaudes.flx 01194 TokenWriter* twflx = new TokenWriter(PrependDirectory(mFaudesDocTemp,"luafaudes.flx")); 01195 01196 // convenience: reinterpret directories 01197 std::set< std::string > srcfiles; 01198 for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) { 01199 std::string sfile = *fit; 01200 if(ExtractExtension(sfile)=="flx") { 01201 srcfiles.insert(sfile); 01202 continue; 01203 } 01204 std::set< std::string > sdir = ReadDirectory(sfile); 01205 sdir=EraseHiddenFiles(sdir); 01206 for(std::set < std::string >::iterator dit=sdir.begin();dit!=sdir.end();dit++) { 01207 sfile=PrependDirectory(*fit,*dit); 01208 srcfiles.insert(sfile); 01209 } 01210 } 01211 01212 // traverse flx-files and extract 01213 for(std::set < std::string >::iterator fit=srcfiles.begin(); fit!=srcfiles.end(); fit++) { 01214 // test extension 01215 std::string ext=ExtractExtension(*fit); 01216 std::string bas=ExtractBasename(*fit); 01217 // cases: flx 01218 if(ext=="flx") { 01219 std::cerr << "flxinstall: extracting lua-extension from \"" << *fit << "\"" << std::endl; 01220 // clear extension context 01221 mReferencePages.clear(); 01222 mLuaFunctions.clear(); 01223 mExtensionName=""; 01224 // extract component files 01225 TokenReader rTr(*fit); 01226 XtractReferencePages(rTr,mFaudesDocTemp); 01227 XtractLuaTutorials(rTr,mFaudesDocTemp); 01228 XtractImageFiles(rTr,mFaudesDocImages); 01229 XtractImageGenFiles(rTr,mFaudesDocTemp); 01230 XtractLuaFunctions(rTr,*twflx); 01231 // autogenerate index if necessary 01232 DefaultIndexPage(mFaudesDocTemp); 01233 continue; 01234 } 01235 } 01236 01237 // copy composed flx file to accompanie luafaudes binary 01238 delete twflx; 01239 FileCopy(PrependDirectory(mFaudesDocTemp,"luafaudes.flx"),mFaudesBinLuaflx); 01240 01241 // report 01242 std::cerr << "flxinstall: generating list of source files" << std::endl; 01243 01244 // record all files relevant to toc 01245 std::set< std::string > tocsource; 01246 // record all basenames to detect doublet fref 01247 std::set< std::string > frefbase; 01248 01249 01250 // collect all fref files for processing to doc/ 01251 std::set< std::string > docsource; 01252 std::set< std::string > docrefsrc = ReadDirectory(mFaudesDocRefsrc); 01253 for(std::set < std::string >::iterator fit=docrefsrc.begin(); fit!=docrefsrc.end(); fit++) { 01254 std::string ext=ExtractExtension(*fit); 01255 std::string bas=ExtractBasename(*fit); 01256 std::string ffile=PrependDirectory(mFaudesDocRefsrc,*fit); 01257 if(ext!="fref") continue; 01258 if(frefbase.find(bas)!=frefbase.end()){ 01259 std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from std dist: ERROR." << std::endl; 01260 exit(1); 01261 } 01262 docsource.insert(ffile); 01263 tocsource.insert(ffile); 01264 frefbase.insert(bas); 01265 } 01266 01267 // collect all fref files for processing to doc/reference 01268 std::set< std::string > docrefsource; 01269 std::set< std::string > docrefsrcref = ReadDirectory(PrependDirectory(mFaudesDocRefsrc,"reference")); 01270 for(std::set < std::string >::iterator fit=docrefsrcref.begin(); fit!=docrefsrcref.end(); fit++) { 01271 std::string ext=ExtractExtension(*fit); 01272 std::string bas=ExtractBasename(*fit); 01273 std::string ffile=PrependDirectory(PrependDirectory(mFaudesDocRefsrc,"reference"),*fit); 01274 if(ext!="fref") continue; 01275 if(frefbase.find(bas)!=frefbase.end()){ 01276 std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from std dist: ERROR." << std::endl; 01277 exit(1); 01278 } 01279 docrefsource.insert(ffile); 01280 tocsource.insert(ffile); 01281 frefbase.insert(bas); 01282 } 01283 std::set< std::string > doctmpdir = ReadDirectory(mFaudesDocTemp); 01284 for(std::set < std::string >::iterator fit=doctmpdir.begin(); fit!=doctmpdir.end(); fit++) { 01285 std::string ext=ExtractExtension(*fit); 01286 std::string bas=ExtractBasename(*fit); 01287 std::string ffile=PrependDirectory(mFaudesDocTemp,*fit); 01288 if(ext!="fref") continue; 01289 if(frefbase.find(bas)!=frefbase.end()){ 01290 std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from ext: ERROR." << std::endl; 01291 exit(1); 01292 } 01293 docrefsource.insert(ffile); 01294 tocsource.insert(ffile); 01295 frefbase.insert(bas); 01296 } 01297 01298 01299 // collect/generate all luatutorial files for processing to doc/luafaudes 01300 std::set< std::string > docluasource; 01301 std::set< std::string > docrefsrclua = ReadDirectory(PrependDirectory(mFaudesDocRefsrc,"luafaudes")); 01302 for(std::set < std::string >::iterator fit=docrefsrclua.begin(); fit!=docrefsrclua.end(); fit++) { 01303 std::string ext=ExtractExtension(*fit); 01304 std::string bas=ExtractBasename(*fit); 01305 std::string ffile=PrependDirectory(PrependDirectory(mFaudesDocRefsrc,"luafaudes"),*fit); 01306 if(ext!="fref") continue; 01307 if(frefbase.find(bas)!=frefbase.end()){ 01308 std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from lua doc: ERROR." << std::endl; 01309 exit(1); 01310 } 01311 docluasource.insert(ffile); 01312 tocsource.insert(ffile); // list of tutorials is required in toc 01313 frefbase.insert(bas); 01314 } 01315 /*std::set< std::string > */tmpfiles = ReadDirectory(mFaudesDocTemp); 01316 for(std::set < std::string >::iterator fit=tmpfiles.begin(); fit!=tmpfiles.end(); fit++) { 01317 std::string ext=ExtractExtension(*fit); 01318 std::string bas=ExtractBasename(*fit); 01319 std::string lfile=PrependDirectory(mFaudesDocTemp,*fit); 01320 std::string ffile=PrependDirectory(mFaudesDocTemp,bas+".fref"); 01321 // skip non-lua 01322 if(ext!="lua") continue; 01323 // test for corresponding fref file 01324 std::string fref = ExtractBasename(*fit) + ".fref"; 01325 if(tmpfiles.find(fref)!=tmpfiles.end()) continue; 01326 // process 01327 Lua2ref(lfile,ffile); 01328 // record (conditional for e.g. dstinstall, where no lua tutorials are generated) 01329 if(FileExists(ffile)) { 01330 docluasource.insert(ffile); 01331 tocsource.insert(ffile); // list of tutorials is required in toc 01332 frefbase.insert(bas); 01333 } 01334 } 01335 01336 // convert/generate full generator images to fref (dest: doc/images) 01337 std::set< std::string > docimgsource; 01338 std::set< std::string > docrefsrcimg = ReadDirectory(PrependDirectory(mFaudesDocRefsrc,"images")); 01339 for(std::set < std::string >::iterator fit=docrefsrcimg.begin(); fit!=docrefsrcimg.end(); fit++) { 01340 std::string ext=ExtractExtension(*fit); 01341 std::string bas=ExtractBasename(*fit); 01342 std::string ffile=PrependDirectory(PrependDirectory(mFaudesDocRefsrc,"images"),*fit); 01343 if(ext!="fref") continue; 01344 docimgsource.insert(ffile); 01345 } 01346 std::set< std::string > imgfiles = ReadDirectory(mFaudesDocTemp); 01347 for(std::set < std::string >::iterator fit=imgfiles.begin(); fit!=imgfiles.end(); fit++) { 01348 std::string ext=ExtractExtension(*fit); 01349 std::string bas=ExtractBasename(*fit); 01350 std::string gfile=PrependDirectory(mFaudesDocTemp,*fit); 01351 std::string ffile=PrependDirectory(mFaudesDocTemp,bas+".fref"); 01352 // skip non-gen 01353 if(ext!="gen") continue; 01354 // test whther we wrote that file 01355 if(mImageFiles.find(gfile)==mImageFiles.end()) continue; 01356 // process to fref 01357 Gen2ref(gfile,ffile); 01358 // record (conditional) 01359 if(FileExists(ffile)) 01360 docimgsource.insert(ffile); 01361 } 01362 01363 01364 // compose toc 01365 std::string toccmd; 01366 for(std::set < std::string >::iterator fit=tocsource.begin(); fit!=tocsource.end(); fit++) { 01367 toccmd+= " " + *fit; 01368 } 01369 toccmd=mFaudesBinRef2html + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -toc " + toccmd 01370 + " " + mFaudesDocToc; 01371 std::cerr << "flxinstall: creating toc" << std::endl; 01372 if(std::system(toccmd.c_str())!=0) { 01373 std::cerr << "flxinstall: processing" << std::endl << toccmd << std::endl; 01374 std::cerr << "flxinstall: error setting up toc: ERROR." << std::endl; 01375 exit(1); 01376 } 01377 std::cerr << "flxinstall: creating toc: done" << std::endl; 01378 01379 01380 // process all pages to doc 01381 std::string doccmd; 01382 for(std::set < std::string >::iterator fit=docsource.begin(); fit!=docsource.end(); fit++) { 01383 doccmd += " " + *fit; 01384 } 01385 doccmd= mFaudesBinRef2html 01386 + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav 01387 + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc 01388 + doccmd + " " + mFaudesDoc; 01389 std::cerr << "flxinstall: processing doc base" << std::endl; 01390 if(std::system(doccmd.c_str())!=0) { 01391 std::cerr << "flxinstall: processing" << std::endl << doccmd << std::endl; 01392 std::cerr << "flxinstall: error while processing doc base: ERROR." << std::endl; 01393 exit(1); 01394 } 01395 std::cerr << "flxinstall: processing doc base: done" << std::endl; 01396 01397 // process all pages to doc/reference 01398 std::string refcmd; 01399 for(std::set < std::string >::iterator fit=docrefsource.begin(); fit!=docrefsource.end(); fit++) { 01400 refcmd += " " + *fit; 01401 } 01402 refcmd= mFaudesBinRef2html 01403 + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav 01404 + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ " 01405 + refcmd + " " + mFaudesDocReference; 01406 std::cerr << "flxinstall: processing user reference" << std::endl; 01407 if(std::system(refcmd.c_str())!=0) { 01408 std::cerr << "flxinstall: processing" << std::endl << refcmd << std::endl; 01409 std::cerr << "flxinstall: error while processing user reference: ERROR." << std::endl; 01410 exit(1); 01411 } 01412 std::cerr << "flxinstall: processing user reference: done" << std::endl; 01413 01414 // process all pages to doc/luafaudes 01415 if(mFaudesDocLuafaudes!="" && docluasource.size()>0) { 01416 std::string luacmd; 01417 for(std::set < std::string >::iterator fit=docluasource.begin(); fit!=docluasource.end(); fit++) { 01418 luacmd += " " + *fit; 01419 } 01420 luacmd= mFaudesBinRef2html 01421 + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav 01422 + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ " 01423 + luacmd + " " + mFaudesDocLuafaudes; 01424 std::cerr << "flxinstall: processing lua tutorial" << std::endl; 01425 if(std::system(luacmd.c_str())!=0) { 01426 std::cerr << "flxinstall: processing" << std::endl << luacmd << std::endl; 01427 std::cerr << "flxinstall: error while processing lua tutorial: ERROR." << std::endl; 01428 exit(1); 01429 } 01430 std::cerr << "flxinstall: processing lua tutorial: done" << std::endl; 01431 } 01432 01433 // process all pages to doc/images/ 01434 if(mFaudesDocImages!="" && docimgsource.size()>0) { 01435 std::string imgcmd; 01436 for(std::set < std::string >::iterator fit=docimgsource.begin(); fit!=docimgsource.end(); fit++) 01437 imgcmd += " " + *fit; 01438 imgcmd= mFaudesBinRef2html 01439 + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav 01440 + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ " 01441 + imgcmd + " " + mFaudesDocImages; 01442 std::cerr << "flxinstall: processing image files" << std::endl; 01443 if(std::system(imgcmd.c_str())!=0) { 01444 std::cerr << "flxinstall: processing" << std::endl << imgcmd << std::endl; 01445 std::cerr << "flxinstall: error while processing image files: ERROR." << std::endl; 01446 exit(1); 01447 } 01448 std::cerr << "flxinstall: processing image files: done" << std::endl; 01449 } 01450 01451 01452 // copy index file: main index 01453 if(FileExists(PrependDirectory(mFaudesDocRefsrc,"faudes_about.fref"))) { 01454 std::string dst=PrependDirectory(mFaudesDoc,"index.html"); 01455 std::string proccmd= mFaudesBinRef2html 01456 + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav 01457 + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ./ " 01458 + PrependDirectory(mFaudesDocRefsrc,"faudes_about.fref") + " " + dst; 01459 std::cerr << "flxinstall: fix html index " << std::endl; 01460 if(std::system(proccmd.c_str())!=0) { 01461 std::cerr << "flxinstall: error when processing index.html: ERROR." <<std::endl; 01462 exit(1); 01463 } 01464 } 01465 01466 // copy index file: luafaudes 01467 if(mFaudesDocLuafaudes!="" && DirectoryExists(PrependDirectory(mFaudesDocRefsrc,"luafaudes"))){ 01468 std::string dst=PrependDirectory(mFaudesDocLuafaudes,"index.html"); 01469 std::string proccmd= mFaudesBinRef2html 01470 + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav 01471 + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ " 01472 + PrependDirectory(mFaudesDocRefsrc,"luafaudes/faudes_luafaudes.fref") + " " + dst; 01473 std::cerr << "flxinstall: fix html index " << std::endl; 01474 if(std::system(proccmd.c_str())!=0) { 01475 std::cerr << "flxinstall: error when processing index.html: ERROR." <<std::endl; 01476 exit(1); 01477 } 01478 } 01479 01480 // copy index file: reference 01481 if(mFaudesDocReference!="" && DirectoryExists(PrependDirectory(mFaudesDocRefsrc,"reference"))){ 01482 std::string dst=PrependDirectory(mFaudesDocReference,"index.html"); 01483 std::string proccmd= mFaudesBinRef2html 01484 + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav 01485 + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ " 01486 + PrependDirectory(mFaudesDocRefsrc,"reference/reference_index.fref") + " " + dst; 01487 std::cerr << "flxinstall: fix html index " << std::endl; 01488 if(std::system(proccmd.c_str())!=0) { 01489 std::cerr << "flxinstall: error when processing index.html: ERROR." <<std::endl; 01490 exit(1); 01491 } 01492 } 01493 01494 // clean tmp 01495 // (dont do so: keep frefs for dstinstall to extract index for qhc) 01496 /* 01497 for(std::set < std::string >::iterator fit=tmpfiles.begin(); fit!=tmpfiles.end(); fit++) { 01498 std::string dfile=PrependDirectory(mFaudesDocTemp,*fit); 01499 RemoveFile(*fit); 01500 } 01501 */ 01502 01503 std::cerr << "flxinstall: done" << std::endl; 01504 01505 01506 01507 } 01508 01509 01510 // ****************************************************************** 01511 // extract extension 01512 // ****************************************************************** 01513 01514 // control 01515 void ExtractExtensionFile(void) { 01516 01517 // test extension 01518 std::string ext=ExtractExtension(mSourceFile); 01519 std::string bas=ExtractBasename(mSourceFile); 01520 if(ext!="flx") 01521 usage_exit("extract must specify a *.flx source"); 01522 // prepare to read 01523 TokenReader tr(mSourceFile); 01524 Token btag; 01525 tr.ReadBegin("LuaExtension",btag); 01526 if(!btag.ExistsAttributeString("name")) { 01527 std::cerr << "flxinstall: lua-extension must have a name attribute " << tr.FileLine() << ": ERROR." << std::endl; 01528 exit(1); 01529 } 01530 mExtensionName=btag.AttributeStringValue("name"); 01531 // scan for relevant sections 01532 while(!tr.Eos("LuaExtension")) { 01533 tr.Peek(btag); 01534 // skip tokens 01535 if(!btag.IsBegin()) { 01536 tr.Get(btag); 01537 continue; 01538 } 01539 // switch sections: fref 01540 if(btag.StringValue()=="ReferencePage") { 01541 // figure destination 01542 if(!btag.ExistsAttributeString("page")) { 01543 std::cerr << "flxinstall: skipping referencepage without page attribute" << std::endl; 01544 tr.ReadBegin(btag.StringValue()); 01545 tr.ReadEnd(btag.StringValue()); 01546 continue; 01547 } 01548 std::string page=mExtensionName + "_" + btag.AttributeStringValue("page") +".fref"; 01549 std::transform(page.begin(), page.end(), page.begin(), tolower); 01550 std::string dstname= mTarget + faudes_pathsep() + page; 01551 std::cerr << "flxinstall: extracting reference page to \"" << dstname << "\"" << std::endl; 01552 // do copy 01553 TokenWriter tw(dstname,"ReferencePage"); 01554 InsertReferencePage(tr,tw,mExtensionName); 01555 continue; 01556 } 01557 // switch sections: lua function 01558 if(btag.StringValue()=="LuaFunctionDefinition") { 01559 // figure destination 01560 if(!btag.ExistsAttributeString("name")) { 01561 std::cerr << "flxinstall: skipping lua function without name attribute" << std::endl; 01562 tr.ReadBegin(btag.StringValue()); 01563 tr.ReadEnd(btag.StringValue()); 01564 continue; 01565 } 01566 std::string name=btag.AttributeStringValue("name"); 01567 size_t pos=name.find("::"); // test this construct for "xyz::" 01568 if(pos!=std::string::npos) name=name.substr(pos+2); 01569 name = name +".rti"; 01570 std::transform(name.begin(), name.end(), name.begin(), tolower); 01571 std::string dstname= mTarget + faudes_pathsep() + name; 01572 std::cerr << "flxinstall: extracting lua function to \"" << dstname << "\"" << std::endl; 01573 // do copy 01574 TokenWriter tw(dstname,"LuaFunctionDefinition"); 01575 InsertLuaFunction(tr,tw); 01576 continue; 01577 } 01578 // switch sections: image file 01579 if(btag.StringValue()=="ImageFile") { 01580 // figure destination 01581 if(!btag.ExistsAttributeString("name")) { 01582 std::cerr << "flxinstall: skipping image file without name attribute" << std::endl; 01583 tr.ReadBegin(btag.StringValue()); 01584 tr.ReadEnd(btag.StringValue()); 01585 continue; 01586 } 01587 std::string name= btag.AttributeStringValue("name"); 01588 std::transform(name.begin(), name.end(), name.begin(), tolower); 01589 std::string dstname= mTarget + faudes_pathsep() + name; 01590 std::cerr << "flxinstall: extracting image file to \"" << dstname << "\"" << std::endl; 01591 TokenWriter tw(dstname); 01592 // read data 01593 tr.ReadBegin("ImageFile"); 01594 Token data; 01595 tr.Get(data); 01596 if(!data.IsBinary()){ 01597 } 01598 // copy to C++ stream 01599 std::fstream fsout; 01600 fsout.exceptions(std::ios::badbit|std::ios::failbit); 01601 try{ 01602 fsout.open(dstname.c_str(), std::ios::out | std::ios::binary); 01603 fsout.write(data.StringValue().c_str(),data.StringValue().size()); 01604 fsout.close(); 01605 } 01606 catch (std::ios::failure&) { 01607 std::cerr << "flxinstall: file io error when writing \"" << dstname << "\"" << std::endl; 01608 } 01609 // done 01610 tr.ReadEnd("ImageFile"); 01611 continue; 01612 } 01613 // switch sections: data file 01614 if(btag.StringValue()=="DataFile") { 01615 // figure destination 01616 if(!btag.ExistsAttributeString("name")) { 01617 std::cerr << "flxinstall: skipping data file without name attribute" << std::endl; 01618 tr.ReadBegin(btag.StringValue()); 01619 tr.ReadEnd(btag.StringValue()); 01620 continue; 01621 } 01622 std::string name= "data" + faudes_pathsep() + btag.AttributeStringValue("name"); 01623 std::transform(name.begin(), name.end(), name.begin(), tolower); 01624 std::string dstname= mTarget + faudes_pathsep() + name; 01625 std::cerr << "flxinstall: extracting data file to \"" << dstname << "\"" << std::endl; 01626 // insist in data directiory 01627 MakeDirectory(mTarget,"data"); 01628 TokenWriter tw(dstname); 01629 // read data 01630 tr.ReadBegin("DataFile"); 01631 Token data; 01632 tr.Peek(data); 01633 // case 1: binary 01634 if(data.IsBinary()){ 01635 tr.Get(data); 01636 // copy to C++ stream 01637 std::fstream fsout; 01638 fsout.exceptions(std::ios::badbit|std::ios::failbit); 01639 try{ 01640 fsout.open(dstname.c_str(), std::ios::out | std::ios::binary); 01641 fsout.write(data.StringValue().c_str(),data.StringValue().size()); 01642 fsout.close(); 01643 } catch (std::ios::failure&) { 01644 std::cerr << "flxinstall: file io error when writing \"" << dstname << "\"" << std::endl; 01645 } 01646 } 01647 // case 2: token stream 01648 else if(data.IsBegin()){ 01649 // copy to token writer 01650 InsertSection(tr,tw,data.StringValue()); 01651 } 01652 // case 3: error 01653 else { 01654 std::cerr << "flxinstall: skipping invalid data " << tr.FileLine() << std::endl; 01655 } 01656 // read end tag 01657 tr.ReadEnd("DataFile"); 01658 continue; 01659 } 01660 // switch sections: data file 01661 if(btag.StringValue()=="LuaTutorial") { 01662 // figure destination 01663 if(!btag.ExistsAttributeString("name")) { 01664 std::cerr << "flxinstall: skipping tutorial without name attribute" << std::endl; 01665 tr.ReadBegin(btag.StringValue()); 01666 tr.ReadEnd(btag.StringValue()); 01667 continue; 01668 } 01669 std::string name=btag.AttributeStringValue("name"); 01670 std::transform(name.begin(), name.end(), name.begin(), tolower); 01671 std::string dstname= mTarget + faudes_pathsep() + name; 01672 std::cerr << "flxinstall: extracting tutorial to \"" << dstname << "\"" << std::endl; 01673 // do copy 01674 TokenWriter tw(dstname); 01675 InsertPlainLuaTutorial(tr,tw); 01676 continue; 01677 } 01678 // skip unknown 01679 tr.ReadBegin(btag.StringValue()); 01680 tr.ReadEnd(btag.StringValue()); 01681 } 01682 // done 01683 tr.ReadEnd("LuaExtension"); 01684 } 01685 01686 // ****************************************************************** 01687 // run test cases 01688 // ****************************************************************** 01689 01690 // uses mSource for std flx 01691 01692 void RunTestCases() { 01693 // insist in luafaudes 01694 if(!FileExists(mFaudesBinLuafaudes)) { 01695 std::cerr << "flxinstall: cannot execute luafaudes" << std::endl; 01696 exit(1); 01697 } 01698 // read target directory to extract lua scripts 01699 std::set< std::string > allfiles = ReadDirectory(mTarget); 01700 std::set< std::string > luascripts; 01701 for(std::set < std::string >::iterator fit=allfiles.begin(); fit!=allfiles.end(); fit++) 01702 if(ExtractExtension(*fit)=="lua") luascripts.insert(*fit); 01703 // loop scripts 01704 for(std::set < std::string >::iterator fit=luascripts.begin(); fit!=luascripts.end(); fit++) { 01705 // build command 01706 std::string cmd = mFaudesBinLuafaudes + " -x " +mSourceFile + " " + *fit; 01707 // run 01708 std::cerr << "flxinstall: execute: " << cmd << std::endl; 01709 int sysret=std::system(cmd.c_str()); 01710 if(sysret!=0) { 01711 std::cerr << "flxinstall: error while running lua script \"" << *fit << "\"" << std::endl; 01712 exit(1); 01713 } 01714 01715 01716 } 01717 01718 01719 } 01720 01721 // ****************************************************************** 01722 // command line ui 01723 // ****************************************************************** 01724 01725 01726 int main(int argc, char *argv[]) { 01727 01728 // local config 01729 bool doc=false; 01730 bool doi=false; 01731 bool dor=false; 01732 bool dox=false; 01733 bool dot=false; 01734 01735 // min args 01736 if(argc < 2) usage_exit(); 01737 01738 // primitive commad line parsing 01739 int i; 01740 for(i=1; i<argc; i++) { 01741 std::string option(argv[i]); 01742 // overwrite doc 01743 if(option=="-tdoc") { 01744 i++; if(i>=argc) usage_exit(); 01745 mFaudesDoc=argv[i]; 01746 continue; 01747 } 01748 // overwrite bin 01749 if(option=="-tbin") { 01750 i++; if(i>=argc) usage_exit(); 01751 mFaudesBin=argv[i]; 01752 continue; 01753 } 01754 // overwrite rti 01755 if(option=="-trti") { 01756 i++; if(i>=argc) usage_exit(); 01757 mFaudesDocRti=argv[i]; 01758 continue; 01759 } 01760 // overwrite cnav 01761 if(option=="-tcnav") { 01762 i++; if(i>=argc) usage_exit(); 01763 mFaudesDocNav=argv[i]; 01764 continue; 01765 } 01766 // overwrite css 01767 if(option=="-tcss") { 01768 i++; if(i>=argc) usage_exit(); 01769 mFaudesDocCss=argv[i]; 01770 continue; 01771 } 01772 // target standalone 01773 if(option=="-tapp") { 01774 mFaudesStandalone = true; 01775 continue; 01776 } 01777 // mode: compile 01778 if(option=="-c") { 01779 i++; doc=true; 01780 break; 01781 } 01782 // mode: install 01783 if(option=="-i") { 01784 i++; doi=true; 01785 break; 01786 } 01787 // mode: remove 01788 if(option=="-r") { 01789 i++; dor=true; 01790 break; 01791 } 01792 // mode: extract 01793 if(option=="-x") { 01794 i++; dox=true; 01795 break; 01796 } 01797 // mode: test 01798 if(option=="-t") { 01799 i++; dot=true; 01800 break; 01801 } 01802 // option: help 01803 if((option=="-?") || (option=="--help")) { 01804 usage_exit(); 01805 continue; 01806 } 01807 // option: unknown 01808 if(option.size()>1) 01809 if(option.at(0)=='-') { 01810 usage_exit("unknown option " + option); 01811 continue; 01812 } 01813 // must choose mode 01814 usage_exit("must set either -c, -i, -r, -x or -t mode" ); 01815 } 01816 01817 // create 01818 if(doc) { 01819 // figure source files 01820 for(;i<argc-1;i++) { 01821 mSourceFiles.insert(std::string(argv[i])); 01822 } 01823 // convenience: if its a directory, use all files inside 01824 if(mSourceFiles.size()==1) { 01825 std::set< std::string > srcfiles = ReadDirectory(std::string(argv[i-1])); 01826 srcfiles=EraseHiddenFiles(srcfiles); 01827 if(srcfiles.size()>0) { 01828 mSourceFiles.clear(); 01829 for(std::set < std::string >::iterator fit=srcfiles.begin(); fit!=srcfiles.end(); fit++) 01830 mSourceFiles.insert(PrependDirectory(std::string(argv[i-1]),*fit)); 01831 } 01832 } 01833 // have a target file 01834 if(!(i<argc)) 01835 usage_exit("target *.flx-file not specified"); 01836 // figure target file 01837 mTarget=std::string(argv[i]); 01838 // consistency: insist in .flx target 01839 if(mTarget!="-") 01840 if(ExtractExtension(mTarget)!="flx") 01841 usage_exit("target *.flx-file not specified"); 01842 // doit 01843 CreateExtensionFile(); 01844 exit(0); 01845 } 01846 01847 // install 01848 if(doi) { 01849 // have at least one source 01850 if(!(i<argc-1)) 01851 usage_exit("source and target must be specified"); 01852 // figure source files 01853 for(;i<argc-1;i++) { 01854 mSourceFiles.insert(std::string(argv[i])); 01855 } 01856 // convenience: if its a directory, use all files inside 01857 if(mSourceFiles.size()==1) { 01858 std::set< std::string > srcfiles = ReadDirectory(std::string(argv[i-1])); 01859 srcfiles=EraseHiddenFiles(srcfiles); 01860 if(srcfiles.size()>0) { 01861 mSourceFiles.clear(); 01862 for(std::set < std::string >::iterator fit=srcfiles.begin(); fit!=srcfiles.end(); fit++) 01863 if(ExtractExtension(*fit)=="flx") 01864 mSourceFiles.insert(PrependDirectory(std::string(argv[i-1]),*fit)); 01865 } 01866 } 01867 // insist in flx source 01868 for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) 01869 if(ExtractExtension(*fit)!="flx") 01870 usage_exit("sources must be *.flx-files: "+ *fit); 01871 // figure target directory 01872 mTarget=std::string(argv[i]); 01873 TestFaudesTarget(); 01874 // doit 01875 InstallExtensionFiles(); 01876 exit(0); 01877 } 01878 01879 // remove 01880 if(dor) { 01881 // have at least one file 01882 if(i!=argc-1) 01883 usage_exit("target not specified"); 01884 // figure target file 01885 mTarget=std::string(argv[i]); 01886 TestFaudesTarget(); 01887 // doit 01888 InstallExtensionFiles(); 01889 if(FileExists(mFaudesBinLuaflx)) FileDelete(mFaudesBinLuaflx); 01890 exit(0); 01891 } 01892 01893 // xtract 01894 if(dox) { 01895 // insist 01896 if(!(i<argc-1)) 01897 usage_exit("source and destination must be specified"); 01898 // figure source 01899 mSourceFile=std::string(argv[i++]); 01900 if(ExtractExtension(mSourceFile)!="flx") 01901 usage_exit("source must be an *.flx-file"); 01902 // destination 01903 mTarget=std::string(argv[i++]); 01904 // test consistent args 01905 if((i<argc)) 01906 usage_exit("too many arguments"); 01907 // doit 01908 MakeDirectory(".",mTarget); 01909 ExtractExtensionFile(); 01910 exit(0); 01911 } 01912 01913 // test 01914 if(dot) { 01915 // insist 01916 if(!(i<argc-1)) 01917 usage_exit("source and temp dir must be specified"); 01918 // figure source 01919 mSourceFile=std::string(argv[i++]); 01920 if(ExtractExtension(mSourceFile)!="flx") 01921 usage_exit("source must be an *.flx-file"); 01922 // destination 01923 mTarget=std::string(argv[i++]); 01924 // test consistent args 01925 if((i<argc)) 01926 usage_exit("too many arguments"); 01927 // insist in target to be the current directory and empty 01928 if((mTarget != ".") && (mTarget != "./")) 01929 usage_exit("target must be \".\" or \"./\""); 01930 std::set< std::string > curdir = ReadDirectory(mTarget); 01931 if(curdir.size()!=0) 01932 usage_exit("target must be empty"); 01933 // test for luafaudes (expects mFaudesBin) 01934 TestLuafaudes(); 01935 // do extract and test 01936 ExtractExtensionFile(); 01937 RunTestCases(); 01938 // done 01939 exit(0); 01940 } 01941 01942 // error 01943 usage_exit(); 01944 01945 // never get here 01946 return 1; 01947 } libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |