flxinstall.cpp
Go to the documentation of this file.
1 /** flxinstall.spp Utility to create/install/remove faudes-lua-extensions */
2 
3 /* FAU Discrete Event Systems Library (libfaudes)
4 
5 Copyright (C) 2011 Thomas Moor
6 
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11 
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
20 
21 
22 
23 #include <string>
24 #include <set>
25 #include <cctype>
26 #include <cstdlib>
27 #include <ctime>
28 #include <iostream>
29 #include <fstream>
30 #include "corefaudes.h"
31 
32 
33 using namespace faudes;
34 
35 // ******************************************************************
36 // error exit
37 // ******************************************************************
38 
39 void usage_exit(const std::string& rMessage="") {
40  // ui hints
41  if(rMessage!="") {
42  std::cerr << "" << std::endl;
43  std::cerr << "flxinstall: " << rMessage << ": ERROR." << std::endl;
44  std::cerr << "" << std::endl;
45  exit(1);
46  }
47  std::cerr << "flxinstall: " << VersionString() << std::endl;
48  std::cerr << "" << std::endl;
49  std::cerr << "utility to create/install/remove faudes-lua-extension "<< std::endl;
50  std::cerr << std::endl << "usage: " << std::endl;
51  std::cerr << "flxinstall <advanced options> <mode> <input-file(s)> <output-file/path>" << std::endl;
52  std::cerr << "with <mode> as follows:" << std::endl;
53  std::cerr << " -c create extension (*.flx file) from input files" << std::endl;
54  std::cerr << " -i install extension (*.flx file) to libFAUDES installation" << std::endl;
55  std::cerr << " -r remove extensions from libFAUDES installation" << std::endl;
56  std::cerr << " -x extract extension (*.flx file) to output directory" << std::endl;
57  std::cerr << " -t extract and test extension (*.flx file) to output directory" << std::endl;
58  std::cerr << std::endl;
59  std::cerr << "advanced options for non-standard target layout" << std::endl;
60  std::cerr << " -tbin <path> location of binaries, default $target/bin" << std::endl;
61  exit(1);
62 }
63 
64 
65 // ******************************************************************
66 // Configuration
67 // ******************************************************************
68 
69 
70 std::string mXmlSeparator = "<!-- ================================================================================ -->";
71 
72 
73 // source/contents/detination
74 std::set < std::string > mSourceFiles;
75 std::string mSourceFile;
76 std::string mTarget;
77 std::string mExtensionName;
78 std::set < std::string > mReferencePages;
79 std::set < std::string > mGeneratorFiles;
80 std::set < std::string > mImageFiles;
81 std::set < std::string > mLuaFunctions;
82 
83 
84 // destination layout (effective, defaults to libfaudes std)
85 std::string mFaudesBase;
86 std::string mFaudesBin;
87 std::string mFaudesBinLuafaudes;
88 std::string mFaudesBinLuaflx;
89 std::string mFaudesBinRef2html;
90 bool mFaudesStandalone = false;
91 std::string mFaudesBinLua2ref;
92 std::string mFaudesDoc;
93 std::string mFaudesDocCss;
94 std::string mFaudesDocToc;
95 std::string mFaudesDocNav;
96 std::string mFaudesDocRti;
97 std::string mFaudesDocReference;
98 std::string mFaudesDocLuafaudes;
99 std::string mFaudesDocImages;
100 std::string mFaudesDocRefsrc;
101 std::string mFaudesDocTemp;
102 
103 
104 
105 // ******************************************************************
106 // helper: make/remove dir
107 // ******************************************************************
108 
109 // mkdir
110 void MakeDirectory(const std::string& rPath, const std::string& rDir="") {
111  std::string dir = rPath;
112  if(rDir!="") dir += faudes_pathsep() + rDir;
113  if(DirectoryExists(dir)) return;
114  std::cerr << "flxinstall: creating dir \"" << dir << "\"" << std::endl;
115  int sysret=std::system(std::string("mkdir " + dir).c_str());
116  if(sysret!=0) {
117  std::cerr << "flxinstall: error while creating directory \"" << dir << "\"" << std::endl;
118  usage_exit();
119  }
120 }
121 
122 
123 // remove unix hidden files from list
124 std::set < std::string > EraseHiddenFiles(const std::set < std::string > & src) {
125  std::set < std::string > res;
126  for(std::set < std::string >::iterator fit=src.begin(); fit!=src.end(); fit++) {
127  if(*fit=="") continue;
128  if((*fit).at(0)=='.') continue;
129  res.insert(*fit);
130  }
131  return res;
132 }
133 
134 
135 
136 // ******************************************************************
137 // helper: lua to ref process
138 // ******************************************************************
139 
140 void Lua2ref(const std::string& rLuaFile, const std::string& rRefFile="") {
141  // bail out
142  if(mFaudesBinLua2ref=="") {
143  std::cerr << "flxinstall: ignoring lua script \"" << rLuaFile << "\"" << std::endl;
144  return;
145  }
146  // set up target
147  std::string dst=rRefFile;
148  if(dst=="") {
149  dst=PrependDirectory(ExtractDirectory(rLuaFile),ExtractBasename(rLuaFile)+ ".fref");
150  }
151  // set up command
152  std::string cmd= mFaudesBinLua2ref + " " + rLuaFile + " > " + dst;
153  // run
154  std::cerr << "flxinstall: converting lua script \"" << rLuaFile << "\"" << std::endl;
155  int sysret=std::system(cmd.c_str());
156  if(sysret!=0) {
157  std::cerr << "flxinstall: error while converting lua script \"" << rLuaFile << "\"" << std::endl;
158  usage_exit();
159  }
160 
161 }
162 
163 // ******************************************************************
164 // helper: gen to ref process
165 // ******************************************************************
166 
167 void Gen2ref(const std::string& rGenFile, const std::string& rRefFile="") {
168  std::cerr << "flxinstall: converting generator file \"" << rGenFile << "\"" << std::endl;
169  std::string bas = ExtractBasename(rGenFile);
170  // set up source and target
171  std::string dst=rRefFile;
172  if(dst=="") {
173  dst=PrependDirectory(ExtractDirectory(rGenFile),bas+".fref");
174  }
175  TokenWriter tw(dst);
176  TokenReader tr(rGenFile);
177  // convert
178  try {
179  // reference page
180  Token btag;
181  btag.SetBegin("ReferencePage");
182  btag.InsAttributeString("chapter","images");
183  btag.InsAttributeString("section","none");
184  btag.InsAttributeString("page","none");
185  btag.InsAttributeString("title","Example Data");
186  tw << btag;
187  // headline
188  tw.WriteCharacterData("<h1> Example Date: "+bas+".gen </h1>\n");
189  // svg image
190  tw.WriteCharacterData("<h3> Dot-processed graph as SVG-image </h3>\n");
191  tw.WriteCharacterData("<object type=\"image/svg+xml\" name=\"graph\" data=\""+bas+".svg\">\n");
192  tw.WriteCharacterData("<a class=\"faudes_image\" href=\""+bas+".svg\">\n");
193  tw.WriteCharacterData("<img src=\"$genfile.png\" title=\"Click on image to download SVG formated file.\" />\n");
194  tw.WriteCharacterData("</a></object>");
195  // headline
196  tw.WriteCharacterData("<h3>Token IO</h3>\n");
197  // copy generator
198  tw.WriteBegin("pre");
199  std::string genstr;
200  tr.ReadSection(genstr);
201  tw.WriteText(genstr); // this will escape critical entities
202  tw.WriteEnd("pre");
203  // close my elements
204  tw.WriteCharacterData("<p>&nbsp;</p><p>&nbsp;</p>\n");
205  tw.WriteEnd("ReferencePage");
206  } catch( faudes::Exception&){
207  std::cerr << "flxinstall: error while converting generator \"" << rGenFile << "\"" << std::endl;
208  usage_exit();
209  }
210 }
211 
212 
213 // ******************************************************************
214 // helper: copy files
215 // ******************************************************************
216 
217 // extract and copy token section
218 void InsertSection(TokenReader& rTr, TokenWriter& rTw, const std::string& mLabel) {
219  // get begin
220  Token btag;
221  rTr.ReadBegin(mLabel,btag);
222  // copy section
223  rTw.Write(btag);
224  std::string scttext;
225  rTr.ReadSection(scttext);
226  rTw.WriteCharacterData(scttext);
227  rTw.WriteEnd(mLabel);
228  // read end tag
229  rTr.ReadEnd(mLabel);
230 }
231 
232 // extract and copy page data
233 void InsertReferencePage(TokenReader& rTr, TokenWriter& rTw, const std::string mSection="") {
234  // get begin
235  Token btag;
236  rTr.ReadBegin("ReferencePage",btag);
237  // fix attributes
238  if(!btag.ExistsAttributeString("chapter"))
239  btag.InsAttributeString("chapter","Reference");
240  if(!btag.ExistsAttributeString("section"))
241  if(mSection!="")
242  btag.InsAttributeString("section",mSection);
243  // copy section
244  rTw.Write(btag);
245  std::string scttext;
246  rTr.ReadSection(scttext);
247  rTw.WriteCharacterData(scttext);
248  rTw.WriteEnd("ReferencePage");
249  // read end tag
250  rTr.ReadEnd("ReferencePage");
251 }
252 
253 
254 // extract and copy luafunction
256  // get begin
257  Token btag;
258  rTr.ReadBegin("LuaFunctionDefinition",btag);
259  // copy section
260  rTw.Write(btag);
261  std::string scttext;
262  rTr.ReadSection(scttext);
263  rTw.WriteCharacterData(scttext);
264  rTw.WriteEnd("LuaFunctionDefinition");
265  rTw.Endl();
266  // read end tag
267  rTr.ReadEnd("LuaFunctionDefinition");
268 }
269 
270 
271 
272 // extract and copy tutorial (from xml to plain)
274  std::string codestr;
275  Token btag;
276  rTr.ReadVerbatim("LuaTutorial", codestr);
277  *rTw.Streamp() << codestr;
278 }
279 
280 
281 // extract and copy tutorial (from plain to xml)
283  // read script file to buffer
284  char* buffer=0;
285  long int size=0;
286  try{
287  rTr.Rewind();
288  rTr.Streamp()->seekg(0, std::ios::end);
289  std::streampos last = rTr.Streamp()->tellg();
290  rTr.Streamp()->seekg(0, std::ios::beg);
291  std::streampos first = rTr.Streamp()->tellg();
292  size=(long int) last-first;
293  buffer = new char[last-first];
294  rTr.Streamp()->read(buffer, last-first);
295  rTr.Rewind();
296  } catch (std::ios::failure&) {
297  std::cerr << "flxinstall: io error when reading \"" << rTr.FileName() << "\": ERROR." << std::endl;
298  exit(1);
299  }
300  // convert (better solution?)
301  std::string bufferstr;
302  bufferstr.assign(buffer,size);
303  // relative destination
304  std::string name=rTr.FileName();
305  name=ExtractFilename(name);
306  // write cdata encoded entry
307  Token btag;
308  btag.SetBegin("LuaTutorial");
309  btag.InsAttributeString("name",name);
310  rTw.WriteVerbatim(btag,bufferstr);
311  // discard buffer
312  delete buffer;
313 }
314 
315 
316 
317 // copy source as binary image file
319  // read image file to buffer
320  char* buffer=0;
321  long int size=0;
322  try{
323  rTr.Rewind();
324  rTr.Streamp()->seekg(0, std::ios::end);
325  std::streampos last = rTr.Streamp()->tellg();
326  rTr.Streamp()->seekg(0, std::ios::beg);
327  std::streampos first = rTr.Streamp()->tellg();
328  size=(long int) last-first;
329  buffer = new char[last-first];
330  rTr.Streamp()->read(buffer, last-first);
331  rTr.Rewind();
332  } catch (std::ios::failure&) {
333  std::cerr << "flxinstall: io error when reading \"" << rTr.FileName() << "\": ERROR." << std::endl;
334  exit(1);
335  }
336  // relative destination
337  std::string name=rTr.FileName();
338  name=ExtractFilename(name);
339  // write Base64 encoded entry
340  Token btag;
341  btag.SetBegin("ImageFile");
342  btag.InsAttributeString("name",name);
343  rTw.Write(btag);
344  rTw.WriteBinary(buffer,size);
345  rTw << "\n";
346  rTw.WriteEnd("ImageFile");
347  // discard buffer
348  delete buffer;
349 }
350 
351 
352 
353 // copy source as binary data file
355  // read data file to buffer
356  char* buffer=0;
357  long int size=0;
358  try{
359  rTr.Rewind();
360  rTr.Streamp()->seekg(0, std::ios::end);
361  std::streampos last = rTr.Streamp()->tellg();
362  rTr.Streamp()->seekg(0, std::ios::beg);
363  std::streampos first = rTr.Streamp()->tellg();
364  size=(long int) last-first;
365  buffer = new char[last-first];
366  rTr.Streamp()->read(buffer, last-first);
367  rTr.Rewind();
368  } catch (std::ios::failure&) {
369  std::cerr << "flxinstall: io error when reading \"" << rTr.FileName() << "\": ERROR." << std::endl;
370  exit(1);
371  }
372  // relative destination
373  std::string name=rTr.FileName();
374  name=ExtractFilename(name);
375  // write Base64 encoded entry
376  Token btag;
377  btag.SetBegin("DataFile");
378  btag.InsAttributeString("name",name);
379  rTw.Write(btag);
380  rTw.WriteBinary(buffer,size);
381  rTw << "\n";
382  rTw.WriteEnd("DataFile");
383  // discard buffer
384  delete buffer;
385 }
386 
387 
388 
389 
390 // ******************************************************************
391 // create
392 // ******************************************************************
393 
394 
395 // control
397 
398  // ************ pass 1: inspect sources
399 
400  // traverse images
401  for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
402  // test extension
403  std::string ext=ExtractExtension(*fit);
404  std::string bas=ExtractBasename(*fit);
405  std::string pbas=ExtractDirectory(*fit)+bas;
406  // case: full generator image
407  if( mSourceFiles.find(pbas + ".gen") != mSourceFiles.end())
408  if( mSourceFiles.find(pbas + ".svg") != mSourceFiles.end())
409  if( mSourceFiles.find(pbas + ".png") != mSourceFiles.end()) {
410  if( mGeneratorFiles.find(pbas) == mGeneratorFiles.end()) {
411  std::cerr << "flxinstall: scanning full generator image \"" << pbas << ".*\"" << std::endl;
412  mGeneratorFiles.insert(pbas);
413  }
414  continue;
415  }
416  // skip non images
417  if(! ((ext=="png") || (ext=="svg") || (ext=="jpeg") || (ext=="jpg") )) continue;
418  // case: std image/binary
419  std::cerr << "flxinstall: scanning image file \"" << *fit << "\"" << std::endl;
420  mImageFiles.insert(*fit);
421  }
422  // traverse luafunctions
423  for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
424  // test extension
425  std::string ext=ExtractExtension(*fit);
426  std::string bas=ExtractBasename(*fit);
427  // cases: luafunction
428  if(ext=="rti" && mImageFiles.find(bas)==mImageFiles.end()) {
429  std::cerr << "flxinstall: scanning luafunction \"" << *fit << "\"" << std::endl;
430  TokenReader tr(*fit);
431  Token btag;
432  tr.ReadBegin("LuaFunctionDefinition",btag);
433  if(!btag.ExistsAttributeString("name")) {
434  std::cerr << "flxinstall: name not specified " << tr.FileLine() << ": ERROR." << std::endl;
435  exit(1);
436  }
437  // extract name and space
438  std::string name;
439  std::string space;
440  name=btag.AttributeStringValue("name");
441  size_t pos=name.find("::");
442  if(pos!=std::string::npos) {
443  space=name.substr(0,pos);
444  name=name.substr(pos+2);
445  }
446  // insist in matching space
447  if(space!="" && mExtensionName!="" && space!=mExtensionName) {
448  std::cerr << "flxinstall: namespace must match extension name" << tr.FileLine() << ": ERROR." << std::endl;
449  exit(1);
450  }
451  mExtensionName=space;
452  // done
453  tr.ReadEnd("LuaFunctionDefinition");
454  }
455  }
456  // traverse ref pages
457  for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
458  // test extension
459  std::string ext=ExtractExtension(*fit);
460  std::string bas=ExtractBasename(*fit);
461  // cases: reference page
462  if(ext=="fref") {
463  std::cerr << "flxinstall: scanning reference page \"" << *fit << "\"" << std::endl;
464  TokenReader tr(*fit);
465  Token btag;
466  tr.ReadBegin("ReferencePage",btag);
467  if(!btag.ExistsAttributeString("page")) {
468  std::cerr << "flxinstall: page not specified " << tr.FileLine() << ": ERROR." << std::endl;
469  exit(1);
470  }
471  if(!btag.ExistsAttributeString("title")) {
472  std::cerr << "flxinstall: title not specified " << tr.FileLine() << std::endl;
473  exit(1);
474  }
475  if(btag.ExistsAttributeString("chapter"))
476  if(btag.AttributeStringValue("chapter")!="Reference") {
477  std::cerr << "flxinstall: chapter must be \"Reference\" " << tr.FileLine() << ": ERROR." << std::endl;
478  exit(1);
479  }
480  if(btag.ExistsAttributeString("section"))
481  if(mExtensionName.size()==0) {
482  mExtensionName=btag.AttributeStringValue("section");
483  }
484  if(btag.ExistsAttributeString("section"))
485  if(mExtensionName!=btag.AttributeStringValue("section")) {
486  std::cerr << "flxinstall: section name \"" << mExtensionName << "\" expected "
487  << tr.FileLine() << ": ERROR." << std::endl;
488  exit(1);
489  }
490  std::string page=btag.AttributeStringValue("page");
491  std::transform(page.begin(), page.end(), page.begin(), tolower);
492  // swallow page number
493  std::string ppage=page;
494  std::size_t upos = ppage.find_first_of("_");
495  std::size_t dpos = 0;
496  for(; dpos < ppage.size();dpos++)
497  if(!isdigit(ppage.at(dpos))) break;
498  if(upos!=std::string::npos)
499  if(upos==dpos)
500  if(upos+1<ppage.size())
501  ppage=ppage.substr(upos+1,ppage.size()-upos-1);
502  // record
503  if(mReferencePages.find(ppage)!=mReferencePages.end()) {
504  std::cerr << "flxinstall: double page label \"" << ppage << "\" "
505  << tr.FileLine() << ": ERROR." << std::endl;
506  exit(1);
507  }
508  mReferencePages.insert(ppage);
509  tr.ReadEnd("ReferencePage");
510  }
511  }
512  if(mReferencePages.find("index")==mReferencePages.end()) {
513  std::cerr << "flxinstall: missing index page, will be generated on installation." << std::endl;
514  }
515 
516 
517  // ************ pass 2: read/copy sources
518 
519  // set up target
520  TokenWriter* ptw=0;
521  if(mTarget=="") {
522  mTarget=mExtensionName + ".flx";
523  std::transform(mTarget.begin(), mTarget.end(), mTarget.begin(), tolower);
524  }
525  if(mTarget!="-")
526  ptw=new TokenWriter(mTarget,"LuaExtension");
527  else
529  // indicate tool version
530  *ptw->Streamp() << "<!-- flxinstall " << VersionString() << " -->" << std::endl;
531  // start tag
532  Token btag;
533  btag.SetBegin("LuaExtension");
534  btag.InsAttributeString("name",mExtensionName);
535  ptw->Write(btag);
536  // traverse files
537  for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
538  // test extension
539  std::string ext=ExtractExtension(*fit);
540  std::string bas=ExtractBasename(*fit);
541  std::string pbas=ExtractDirectory(*fit)+bas;
542  // cases: reference page
543  if(ext=="fref") {
544  std::cerr << "flxinstall: appending reference page from \"" << *fit << "\"" << std::endl;
545  *ptw << "\n" << "\n";
546  *ptw->Streamp() << mXmlSeparator << std::endl;
547  *ptw->Streamp() << mXmlSeparator << std::endl;
548  *ptw->Streamp() << mXmlSeparator << std::endl;
549  *ptw->Streamp() << "<!-- reference page from source \"" << *fit << "\" -->" << std::endl;
550  TokenReader tr(*fit);
552  continue;
553  }
554  // cases: code
555  if(ext=="rti") {
556  std::cerr << "flxinstall: appending lua function from \"" << *fit << "\"" << std::endl;
557  *ptw << "\n" << "\n";
558  *ptw->Streamp() << mXmlSeparator << std::endl;
559  *ptw->Streamp() << mXmlSeparator << std::endl;
560  *ptw->Streamp() << mXmlSeparator << std::endl;
561  *ptw->Streamp() << "<!-- lua function from source \"" << *fit << "\" -->" << std::endl;
562  TokenReader tr(*fit);
563  InsertLuaFunction(tr,*ptw);
564  continue;
565  }
566  // cases: binary image
567  if(mImageFiles.find(*fit)!=mImageFiles.end()) {
568  std::cerr << "flxinstall: appending image/binary file from \"" << *fit << "\"" << std::endl;
569  *ptw << "\n" << "\n";
570  *ptw->Streamp() << mXmlSeparator << std::endl;
571  *ptw->Streamp() << mXmlSeparator << std::endl;
572  *ptw->Streamp() << mXmlSeparator << std::endl;
573  *ptw->Streamp() << "<!-- binary file from source \"" << *fit << "\" -->" << std::endl;
574  TokenReader tr(*fit);
575  InsertImageFile(tr,*ptw);
576  continue;
577  }
578  // cases: full generator image
579  if(mGeneratorFiles.find(pbas)!=mGeneratorFiles.end()) {
580  std::cerr << "flxinstall: appending full generator from \"" << pbas << ".*\"" << std::endl;
581  *ptw << "\n" << "\n";
582  *ptw->Streamp() << mXmlSeparator << std::endl;
583  *ptw->Streamp() << mXmlSeparator << std::endl;
584  *ptw->Streamp() << mXmlSeparator << std::endl;
585  *ptw->Streamp() << "<!-- full generator image from source \"" << pbas << ".*\" -->" << std::endl;
586  TokenReader trg(pbas+".gen");
587  InsertImageFile(trg,*ptw);
588  *ptw << "\n";
589  TokenReader trs(pbas+".svg");
590  InsertImageFile(trs,*ptw);
591  *ptw << "\n";
592  TokenReader trp(pbas+".png");
593  InsertImageFile(trp,*ptw);
594  mGeneratorFiles.erase(pbas);
595  continue;
596  }
597  // cases: tutorial
598  if(ext=="lua") {
599  std::cerr << "flxinstall: appending tutorial from \"" << *fit << "\"" << std::endl;
600  *ptw << "\n" << "\n";
601  *ptw->Streamp() << mXmlSeparator << std::endl;
602  *ptw->Streamp() << mXmlSeparator << std::endl;
603  *ptw->Streamp() << mXmlSeparator << std::endl;
604  *ptw->Streamp() << "<!-- tutorial from source \"" << *fit << "\" -->" << std::endl;
605  TokenReader tr(*fit);
606  InsertLuaTutorial(tr,*ptw);
607  continue;
608  }
609  // cases: data directory
610  if(ext=="" && bas=="data") {
611  std::set< std::string > datafiles = ReadDirectory(*fit);
612  datafiles=EraseHiddenFiles(datafiles);
613  if(datafiles.size()==0) continue;
614  std::cerr << "flxinstall: appending data files \"" << *fit << "\"" << std::endl;
615  *ptw << "\n" << "\n";
616  *ptw->Streamp() << mXmlSeparator << std::endl;
617  *ptw->Streamp() << mXmlSeparator << std::endl;
618  *ptw->Streamp() << mXmlSeparator << std::endl;
619  *ptw->Streamp() << "<!-- data from source \"" << *fit << "\" -->" << std::endl;
620  std::set< std::string >::iterator dit;
621  for(dit=datafiles.begin();dit!=datafiles.end();dit++) {
622  std::string srcfile=PrependDirectory(*fit,*dit);
623  TokenReader tr(srcfile);
624  InsertDataFile(tr,*ptw);
625  }
626  }
627  }
628  // cleanup/close
629  *ptw << "\n" << "\n";
630  ptw->WriteEnd("LuaExtension");
631  delete ptw;
632 }
633 
634 
635 // ******************************************************************
636 // test libfaudes installation
637 // ******************************************************************
638 
639 // inspect libfaudes distribution to locate luafaudes (use mFaudesBin)
640 void TestLuafaudes(void) {
641  // read bin dir
643  std::cerr << "flxinstall: cannot open libfaudes binary path \"" << mFaudesBin << "\": ERROR." << std::endl;
644  exit(1);
645  }
646  std::set< std::string > binfiles = ReadDirectory(mFaudesBin);
647  // find luafaudes
649  if(binfiles.find("luafaudes.exe")!= binfiles.end()) {
651  }
652  if(binfiles.find("luafaudes")!= binfiles.end()) {
654  }
656  std::cerr << "flxinstall: warning: cannot open luafaudes in \"" << mFaudesBin << "\"" << std::endl;
658  }
659 }
660 
661 // inspect libfaudes distribution
662 void TestFaudesTarget(void) {
664  std::set< std::string > faudesfiles = ReadDirectory(mFaudesBase);
665  // bad dir
666  if(faudesfiles.empty()) {
667  std::cerr << "flxinstall: cannot open target directory \"" << mFaudesBase << "\": ERROR." << std::endl;
668  exit(1);
669  }
670  // bin (allow overwrite)
671  if(mFaudesBin=="") {
673  if(faudesfiles.find("bin")!= faudesfiles.end())
675  }
677  std::cerr << "flxinstall: cannot open libfaudes binary path in \"" << mFaudesBin << "\": ERROR." << std::endl;
678  exit(1);
679  }
680  std::set< std::string > binfiles = ReadDirectory(mFaudesBin);
681  // insist in ref2html
683  if(binfiles.find("ref2html.exe")!= binfiles.end()) {
685  }
686  if(binfiles.find("ref2html")!= binfiles.end()) {
688  }
689  if(mFaudesBinRef2html=="") {
690  std::cerr << "flxinstall: cannot open ref2html tool in \"" << mFaudesBin << "\": ERROR." << std::endl;
691  exit(1);
692  }
693  // ref2html options
694  if(mFaudesStandalone) mFaudesBinRef2html += " -app";
695  // find luafaudes
696  TestLuafaudes();
697  // default flx
699  // doc (allow overwrite)
700  if(mFaudesDoc=="") {
702  if(faudesfiles.find("doc")!= faudesfiles.end()) {
704  } else if(faudesfiles.find("Doc")!= faudesfiles.end()) {
706  } else if(faudesfiles.find("Documentation")!= faudesfiles.end()) {
707  mFaudesDoc=PrependDirectory(mFaudesDoc,"Documentation");
708  }
710  std::cerr << "flxinstall: cannot open libfaudes documentation path in \"" << mFaudesBase << "\": ERROR." << std::endl;
711  exit(1);
712  }
713  }
715  std::cerr << "flxinstall: cannot open libfaudes documentation path at \"" << mFaudesDoc << "\": ERROR." << std::endl;
716  exit(1);
717  }
718  std::set< std::string > docfiles = ReadDirectory(mFaudesDoc);
719  // css (allow overwrite)
720  if(mFaudesDocCss=="") mFaudesDocCss="faudes.css";
721  mFaudesDocCss=ExtractFilename(mFaudesDocCss); // ignore directory
722  // reference
724  if(docfiles.find("reference")!= docfiles.end()) {
726  } else if(docfiles.find("Reference")!= faudesfiles.end()) {
728  }
730  std::cerr << "flxinstall: cannot open libfaudes reference path in \"" << mFaudesDoc << "\": ERROR." << std::endl;
731  exit(1);
732  }
733  std::set< std::string > regfiles = ReadDirectory(mFaudesDocReference);
734  // luafaudes doc (default: non-existent)
736  if(docfiles.find("luafaudes")!= docfiles.end()) {
738  } else if(docfiles.find("Luafaudes")!= docfiles.end()) {
740  }
741  // lua2ref (try luafaudes on lua2ref.lua)
742  if(mFaudesBinLuafaudes!="") {
743  std::string script = mFaudesBase + faudes_pathsep() + "tools" + faudes_pathsep()
744  + "lua2ref" + faudes_pathsep() + "lua2ref.lua";
745  mFaudesBinLua2ref=mFaudesBinLuafaudes + " " + script;
746  if(!FileExists(script)) mFaudesBinLua2ref = "";
748  std::cerr << "flxinstall: cannot find converter \"lua2ref.lua\"" << std::endl;
749  mFaudesBinLua2ref = "";
750  }
751  }
752  // lua2ref (try perl on lua2ref.pl)
753  if(mFaudesBinLua2ref=="") {
755  + "lua2ref" + faudes_pathsep() + "lua2ref.pl";
757  std::cerr << "flxinstall: cannot find converter \"lua2ref.pl\"" << std::endl;
758  mFaudesBinLua2ref = "";
759  }
760  }
761  if(mFaudesBinLua2ref=="") {
762  std::cerr << "flxinstall: cannot process lua tutorial sources: ERROR." << std::endl;
763  }
764  // images
765  mFaudesDocImages="";
766  if(docfiles.find("images")!= docfiles.end()) {
768  } else {
769  std::cerr << "flxinstall: cannot open images in \"" << mFaudesDoc << "\": ERROR." << std::endl;
770  exit(1);
771  }
772  // refsrc
773  mFaudesDocRefsrc="";
774  if(docfiles.find("refsrc")!= docfiles.end()) {
776  } else {
777  std::cerr << "flxinstall: cannot open refsrc in \"" << mFaudesDoc << "\": ERROR." << std::endl;
778  exit(1);
779  }
780  std::set< std::string > refsrcfiles = ReadDirectory(mFaudesDocRefsrc);
781  // rti (allow overwrite)
784  std::cerr << "flxinstall: cannot open libfaudes.rti at \"" << mFaudesDocRti << "\": ERROR." << std::endl;
785  exit(1);
786  }
787  // cnav (allow overwrite)
788  if(mFaudesDocNav=="") mFaudesDocNav="faudes_navigation.include_fref";
789  mFaudesDocNav=ExtractFilename(mFaudesDocNav); // ignore directory
792  std::cerr << "flxinstall: cannot open navigation file \"" << mFaudesDocNav << "\": ERROR." << std::endl;
793  exit(1);
794  }
795  // temp
797  if(docfiles.find("tmp_flx")== docfiles.end()) {
798  std::cerr << "flxinstall: creating temp dir \"" << mFaudesDocTemp << "\"" << std::endl;
800  }
802 }
803 
804 
805 // ******************************************************************
806 // extract reference pages
807 // ******************************************************************
808 
809 
810 void XtractReferencePages(TokenReader& rTr, const std::string& rDstDir) {
811  // read outer tag
812  Token btag;
813  rTr.Rewind();
814  rTr.ReadBegin("LuaExtension",btag);
815  if(!btag.ExistsAttributeString("name")) {
816  std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl;
817  exit(1);
818  }
819  mExtensionName=btag.AttributeStringValue("name");
820  // scan for reference page sections
821  while(!rTr.Eos("LuaExtension")) {
822  rTr.Peek(btag);
823  // skip tokens
824  if(!btag.IsBegin()) {
825  rTr.Get(btag);
826  continue;
827  }
828  // skip sections
829  if(btag.StringValue()!="ReferencePage") {
830  rTr.ReadBegin(btag.StringValue());
831  rTr.ReadEnd(btag.StringValue());
832  continue;
833  }
834  // extract title & friends
835  std::string title="libFAUDES Reference";
836  if(btag.ExistsAttributeString("title"))
837  title=btag.AttributeStringValue("title");
838  std::string chapter="Reference";
839  if(btag.ExistsAttributeString("chapter"))
840  chapter=btag.AttributeStringValue("chapter");
841  std::string section="";
842  if(btag.ExistsAttributeString("section"))
843  section=btag.AttributeStringValue("section");
844  std::string page="";
845  if(btag.ExistsAttributeString("page"))
846  page=btag.AttributeStringValue("page");
847  // insist in page and section
848  if(page=="" || section=="") {
849  std::cerr << "flxinstall: skipping undefined page at " << rTr.FileLine() << std::endl;
850  rTr.ReadBegin("ReferencePage",btag);
851  rTr.ReadEnd("ReferencePage");
852  continue;
853  }
854  // normalize & report
855  std::transform(section.begin(), section.end(), section.begin(), tolower);
856  std::transform(page.begin(), page.end(), page.begin(), tolower);
857  // swallow page number
858  std::string ppage=page;
859  std::size_t upos = ppage.find_first_of("_");
860  std::size_t dpos = 0;
861  for(; dpos < ppage.size();dpos++)
862  if(!isdigit(ppage.at(dpos))) break;
863  if(upos!=std::string::npos)
864  if(upos==dpos)
865  if(upos+1<ppage.size())
866  ppage=ppage.substr(upos+1,ppage.size()-upos-1);
867  // basename
868  std::string basename= section + "_" + ppage;
869  mReferencePages.insert(basename);
870  // dst file
871  std::string dstfile=rDstDir + faudes_pathsep() + basename + ".fref";
872  std::cerr << "flxinstall: extracting reference page to \"" << dstfile << "\"" << std::endl;
873  TokenWriter dst(dstfile);
874  InsertReferencePage(rTr,dst);
875  }
876 }
877 
878 // ******************************************************************
879 // extract image files
880 // ******************************************************************
881 
882 
883 void XtractImageFiles(TokenReader& rTr,const std::string& rDstDir) {
884  // read outer tag
885  Token btag;
886  rTr.Rewind();
887  rTr.ReadBegin("LuaExtension",btag);
888  if(!btag.ExistsAttributeString("name")) {
889  std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl;
890  exit(1);
891  }
892  mExtensionName=btag.AttributeStringValue("name");
893  // scan for image files
894  while(!rTr.Eos("LuaExtension")) {
895  rTr.Peek(btag);
896  // skip tokens
897  if(!btag.IsBegin()) {
898  rTr.Get(btag);
899  continue;
900  }
901  // skip sections
902  if(btag.StringValue()!="ImageFile") {
903  rTr.ReadBegin(btag.StringValue());
904  rTr.ReadEnd(btag.StringValue());
905  continue;
906  }
907  // read begin tag
908  rTr.ReadBegin("ImageFile",btag);
909  std::string name=btag.AttributeStringValue("name");
910  if(name==""){
911  std::cerr << "flxinstall: image file must specify name " << rTr.FileLine() << std::endl;
912  rTr.ReadEnd("ImageFile");
913  continue;
914  }
915  // skip non-image formats
916  std::string ext = ExtractExtension(name);
917  if(ext!="png" && ext!="svg" && ext!="jpg" && ext!="jpeg") {
918  rTr.ReadEnd("ImageFile");
919  continue;
920  }
921  // read data
922  Token data;
923  rTr.Get(data);
924  if(!data.IsBinary()){
925  std::cerr << "flxinstall: skipping invalid image data " << rTr.FileLine() << std::endl;
926  rTr.ReadEnd("ImageFile");
927  continue;
928  }
929  // dst file
930  std::transform(name.begin(), name.end(), name.begin(), tolower);
931  std::string dstfile=rDstDir + faudes_pathsep() + name;
932  std::cerr << "flxinstall: extracting image to \"" << dstfile << "\"" << std::endl;
933  // record
934  mImageFiles.insert(dstfile);
935  // setup stream
936  std::fstream fsout;
937  fsout.exceptions(std::ios::badbit|std::ios::failbit);
938  try{
939  fsout.open(dstfile.c_str(), std::ios::out | std::ios::binary);
940  fsout.write(data.StringValue().c_str(),data.StringValue().size());
941  fsout.close();
942  }
943  catch (std::ios::failure&) {
944  std::cerr << "flxinstall: file io error when writing \"" << dstfile << "\"" << std::endl;
945  }
946  // read end tag
947  rTr.ReadEnd("ImageFile");
948  }
949 }
950 
951 void XtractImageGenFiles(TokenReader& rTr,const std::string& rDstDir) {
952  // read outer tag
953  Token btag;
954  rTr.Rewind();
955  rTr.ReadBegin("LuaExtension",btag);
956  if(!btag.ExistsAttributeString("name")) {
957  std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl;
958  exit(1);
959  }
960  mExtensionName=btag.AttributeStringValue("name");
961  // scan for image files
962  while(!rTr.Eos("LuaExtension")) {
963  rTr.Peek(btag);
964  // skip tokens
965  if(!btag.IsBegin()) {
966  rTr.Get(btag);
967  continue;
968  }
969  // skip sections
970  if(btag.StringValue()!="ImageFile") {
971  rTr.ReadBegin(btag.StringValue());
972  rTr.ReadEnd(btag.StringValue());
973  continue;
974  }
975  // read begin tag
976  rTr.ReadBegin("ImageFile",btag);
977  std::string name=btag.AttributeStringValue("name");
978  if(name==""){
979  std::cerr << "flxinstall: image file must specify name " << rTr.FileLine() << std::endl;
980  rTr.ReadEnd("ImageFile");
981  continue;
982  }
983  // skip non-gen formats
984  std::string ext = ExtractExtension(name);
985  if(ext!="gen"){
986  rTr.ReadEnd("ImageFile");
987  continue;
988  }
989  // read data
990  Token data;
991  rTr.Get(data);
992  if(!data.IsBinary()){
993  std::cerr << "flxinstall: skipping invalid image data " << rTr.FileLine() << std::endl;
994  rTr.ReadEnd("ImageFile");
995  continue;
996  }
997  // dst file
998  std::transform(name.begin(), name.end(), name.begin(), tolower);
999  std::string dstfile=rDstDir + faudes_pathsep() + name;
1000  std::cerr << "flxinstall: extracting image to \"" << dstfile << "\"" << std::endl;
1001  // record
1002  mImageFiles.insert(dstfile);
1003  // setup stream
1004  std::fstream fsout;
1005  fsout.exceptions(std::ios::badbit|std::ios::failbit);
1006  try{
1007  fsout.open(dstfile.c_str(), std::ios::out | std::ios::binary);
1008  fsout.write(data.StringValue().c_str(),data.StringValue().size());
1009  fsout.close();
1010  }
1011  catch (std::ios::failure&) {
1012  std::cerr << "flxinstall: file io error when writing \"" << dstfile << "\"" << std::endl;
1013  }
1014  // read end tag
1015  rTr.ReadEnd("ImageFile");
1016  }
1017 }
1018 
1019 
1020 // ******************************************************************
1021 // extract lua code
1022 // ******************************************************************
1023 
1024 
1025 
1027  // read outer tag
1028  Token btag;
1029  rTr.Rewind();
1030  rTr.ReadBegin("LuaExtension",btag);
1031  if(!btag.ExistsAttributeString("name")) {
1032  std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl;
1033  exit(1);
1034  }
1035  mExtensionName=btag.AttributeStringValue("name");
1036  // scan for lua function definitions
1037  while(!rTr.Eos("LuaExtension")) {
1038  rTr.Peek(btag);
1039  // skip tokens
1040  if(!btag.IsBegin()) {
1041  rTr.Get(btag);
1042  continue;
1043  }
1044  // skip sections
1045  if(btag.StringValue()!="LuaFunctionDefinition") {
1046  rTr.ReadBegin(btag.StringValue());
1047  rTr.ReadEnd(btag.StringValue());
1048  continue;
1049  }
1050  // extract title & friends
1051  std::string name;
1052  std::string space;
1053  if(btag.ExistsAttributeString("name")){
1054  name=btag.AttributeStringValue("name");
1055  size_t pos=name.find("::");
1056  if(pos!=std::string::npos) {
1057  space=name.substr(0,pos);
1058  name=name.substr(pos+2);
1059  }
1060  }
1061  // insist in name
1062  if(name=="") {
1063  std::cerr << "flxinstall: skipping undefined lua function at " << rTr.FileLine() << std::endl;
1064  rTr.ReadBegin("LuaFunctionDefinition",btag);
1065  rTr.ReadEnd("LuafunctionDefinition");
1066  continue;
1067  }
1068  // insist in space to match
1069  /*
1070  if(space!=mExtensionName) {
1071  std::cerr << "flxinstall: skipping undefined lua function at " << rTr.FileLine() << std::endl;
1072  rTr.ReadBegin("LuaFunctionDefinition",btag);
1073  rTr.ReadEnd("LuafunctionDefinition");
1074  continue;
1075  }
1076  */
1077  // record
1078  mLuaFunctions.insert(name);
1079  // copy
1080  std::cerr << "flxinstall: extracting lua function \"" << name << "\"" << std::endl;
1081  *rTw.Streamp() << mXmlSeparator << std::endl;
1082  *rTw.Streamp() << mXmlSeparator << std::endl;
1083  *rTw.Streamp() << "<!-- lua function from lua-extension " << rTr.FileLine() << " -->" << std::endl;
1084  InsertLuaFunction(rTr,rTw);
1085  }
1086 }
1087 
1088 // ******************************************************************
1089 // extract lua tutorials
1090 // ******************************************************************
1091 
1092 void XtractLuaTutorials(TokenReader& rTr, const std::string& rDstDir) {
1093  // read outer tag
1094  Token btag;
1095  rTr.Rewind();
1096  rTr.ReadBegin("LuaExtension",btag);
1097  if(!btag.ExistsAttributeString("name")) {
1098  std::cerr << "flxinstall: lua-extension must have a name attribute " << rTr.FileLine() << ": ERROR." << std::endl;
1099  exit(1);
1100  }
1101  mExtensionName=btag.AttributeStringValue("name");
1102  // scan for reference page sections
1103  while(!rTr.Eos("LuaExtension")) {
1104  rTr.Peek(btag);
1105  // skip tokens
1106  if(!btag.IsBegin()) {
1107  rTr.Get(btag);
1108  continue;
1109  }
1110  // skip sections
1111  if(btag.StringValue()!="LuaTutorial") {
1112  rTr.ReadBegin(btag.StringValue());
1113  rTr.ReadEnd(btag.StringValue());
1114  continue;
1115  }
1116  // test for name
1117  std::string name=btag.AttributeStringValue("name");
1118  if(name==""){
1119  std::cerr << "flxinstall: lua tutorial must specify name " << rTr.FileLine() << std::endl;
1120  rTr.ReadEnd("LuaTutorial");
1121  continue;
1122  }
1123  // set up destination and copy
1124  std::transform(name.begin(), name.end(), name.begin(), tolower);
1125  std::string dstfile=rDstDir + faudes_pathsep() + name;
1126  std::cerr << "flxinstall: extracting lua tutorial to \"" << dstfile << "\"" << std::endl;
1127  TokenWriter tw(dstfile);
1128  InsertPlainLuaTutorial(rTr,tw);
1129  }
1130 }
1131 
1132 // ******************************************************************
1133 // generate default reference page
1134 // ******************************************************************
1135 
1136 void DefaultIndexPage(const std::string& rDstDir) {
1137  // name of index files
1138  std::string index=mExtensionName + "_index";
1139  std::transform(index.begin(), index.end(), index.begin(), tolower);
1140  // test existence
1141  if(mReferencePages.find(index)!=mReferencePages.end()) {
1142  std::cerr << "flxinstall: index page provided" << std::endl;
1143  return;
1144  }
1145  // error case
1146  if(mReferencePages.size()>0) {
1147  std::cerr << "flxinstall: reference page missing: \"" << index << ".fref\": ERROR" << std::endl;
1148  exit(1);
1149  }
1150  // generates defaultindex page
1151  std::cerr << "flxinstall: generate index page" << std::endl;
1152  TokenWriter tw(rDstDir + faudes_pathsep() + index + ".fref","ReferencePage");
1153  *tw.Streamp() << "<!-- flxinstall " << VersionString() << ": auto generated index -->" << std::endl;
1154  *tw.Streamp() << "<ReferencePage chapter=\"Reference\" section=\"" << mExtensionName <<
1155  "\" page=\"0_Index\" title=\""<< mExtensionName << " Index\" >" << std::endl;
1156  // headline
1157  *tw.Streamp() << "<h1> " << mExtensionName << ": Functions </h1>" << std::endl;
1158  // list functions
1159  std::set< std::string >::iterator fit;
1160  for(fit=mLuaFunctions.begin(); fit!= mLuaFunctions.end(); fit++) {
1161  *tw.Streamp() << "<ffnct_reference name=\"" << *fit << "\" />" << std::endl;
1162  }
1163  // done
1164  *tw.Streamp() << "</ReferencePage>" << std::endl;
1165 }
1166 
1167 
1168 
1169 
1170 // ******************************************************************
1171 // install extension
1172 // ******************************************************************
1173 
1174 // control
1176 
1177  // clear context
1178  mImageFiles.clear();
1179 
1180  // clean tmp (this is for dstinstall to see only relevant files in the temp directory)
1181  std::set< std::string > tmpfiles = ReadDirectory(mFaudesDocTemp);
1182  for(std::set < std::string >::iterator fit=tmpfiles.begin(); fit!=tmpfiles.end(); fit++) {
1183  std::string dfile=PrependDirectory(mFaudesDocTemp,*fit);
1184  if(!RemoveFile(dfile)) {
1185  std::cerr << "flxinstall: failed to remove \"" << *fit << "\"" << std::endl;
1186  };
1187  }
1188 
1189  // prepare luafaudes.flx
1190  TokenWriter* twflx = new TokenWriter(PrependDirectory(mFaudesDocTemp,"luafaudes.flx"));
1191 
1192  // convenience: reinterpret directories
1193  std::set< std::string > srcfiles;
1194  for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++) {
1195  std::string sfile = *fit;
1196  if(ExtractExtension(sfile)=="flx") {
1197  srcfiles.insert(sfile);
1198  continue;
1199  }
1200  std::set< std::string > sdir = ReadDirectory(sfile);
1201  sdir=EraseHiddenFiles(sdir);
1202  for(std::set < std::string >::iterator dit=sdir.begin();dit!=sdir.end();dit++) {
1203  sfile=PrependDirectory(*fit,*dit);
1204  srcfiles.insert(sfile);
1205  }
1206  }
1207 
1208  // traverse flx-files and extract
1209  for(std::set < std::string >::iterator fit=srcfiles.begin(); fit!=srcfiles.end(); fit++) {
1210  // test extension
1211  std::string ext=ExtractExtension(*fit);
1212  std::string bas=ExtractBasename(*fit);
1213  // cases: flx
1214  if(ext=="flx") {
1215  std::cerr << "flxinstall: extracting lua-extension from \"" << *fit << "\"" << std::endl;
1216  // clear extension context
1217  mReferencePages.clear();
1218  mLuaFunctions.clear();
1219  mExtensionName="";
1220  // extract component files
1221  TokenReader rTr(*fit);
1226  XtractLuaFunctions(rTr,*twflx);
1227  // autogenerate index if necessary
1229  continue;
1230  }
1231  }
1232 
1233  // copy composed flx file to accompanie luafaudes binary
1234  delete twflx;
1236 
1237  // report
1238  std::cerr << "flxinstall: generating list of source files" << std::endl;
1239 
1240  // record all files relevant to toc
1241  std::set< std::string > tocsource;
1242  // record all basenames to detect doublet fref
1243  std::set< std::string > frefbase;
1244 
1245 
1246  // collect all fref files for processing to doc/
1247  std::set< std::string > docsource;
1248  std::set< std::string > docrefsrc = ReadDirectory(mFaudesDocRefsrc);
1249  for(std::set < std::string >::iterator fit=docrefsrc.begin(); fit!=docrefsrc.end(); fit++) {
1250  std::string ext=ExtractExtension(*fit);
1251  std::string bas=ExtractBasename(*fit);
1252  std::string ffile=PrependDirectory(mFaudesDocRefsrc,*fit);
1253  if(ext!="fref") continue;
1254  if(frefbase.find(bas)!=frefbase.end()){
1255  std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from std dist: ERROR." << std::endl;
1256  exit(1);
1257  }
1258  docsource.insert(ffile);
1259  tocsource.insert(ffile);
1260  frefbase.insert(bas);
1261  }
1262 
1263  // collect all fref files for processing to doc/reference
1264  std::set< std::string > docrefsource;
1265  std::set< std::string > docrefsrcref = ReadDirectory(PrependDirectory(mFaudesDocRefsrc,"reference"));
1266  for(std::set < std::string >::iterator fit=docrefsrcref.begin(); fit!=docrefsrcref.end(); fit++) {
1267  std::string ext=ExtractExtension(*fit);
1268  std::string bas=ExtractBasename(*fit);
1269  std::string ffile=PrependDirectory(PrependDirectory(mFaudesDocRefsrc,"reference"),*fit);
1270  if(ext!="fref") continue;
1271  if(frefbase.find(bas)!=frefbase.end()){
1272  std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from std dist: ERROR." << std::endl;
1273  exit(1);
1274  }
1275  docrefsource.insert(ffile);
1276  tocsource.insert(ffile);
1277  frefbase.insert(bas);
1278  }
1279  std::set< std::string > doctmpdir = ReadDirectory(mFaudesDocTemp);
1280  for(std::set < std::string >::iterator fit=doctmpdir.begin(); fit!=doctmpdir.end(); fit++) {
1281  std::string ext=ExtractExtension(*fit);
1282  std::string bas=ExtractBasename(*fit);
1283  std::string ffile=PrependDirectory(mFaudesDocTemp,*fit);
1284  if(ext!="fref") continue;
1285  if(frefbase.find(bas)!=frefbase.end()){
1286  std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from ext: ERROR." << std::endl;
1287  exit(1);
1288  }
1289  docrefsource.insert(ffile);
1290  tocsource.insert(ffile);
1291  frefbase.insert(bas);
1292  }
1293 
1294 
1295  // collect/generate all luatutorial files for processing to doc/luafaudes
1296  std::set< std::string > docluasource;
1297  std::set< std::string > docrefsrclua = ReadDirectory(PrependDirectory(mFaudesDocRefsrc,"luafaudes"));
1298  for(std::set < std::string >::iterator fit=docrefsrclua.begin(); fit!=docrefsrclua.end(); fit++) {
1299  std::string ext=ExtractExtension(*fit);
1300  std::string bas=ExtractBasename(*fit);
1301  std::string ffile=PrependDirectory(PrependDirectory(mFaudesDocRefsrc,"luafaudes"),*fit);
1302  if(ext!="fref") continue;
1303  if(frefbase.find(bas)!=frefbase.end()){
1304  std::cerr << "flxinstall: reference file doublet \"" << *fit << "\" from lua doc: ERROR." << std::endl;
1305  exit(1);
1306  }
1307  docluasource.insert(ffile);
1308  tocsource.insert(ffile); // list of tutorials is required in toc
1309  frefbase.insert(bas);
1310  }
1311  /*std::set< std::string > */tmpfiles = ReadDirectory(mFaudesDocTemp);
1312  for(std::set < std::string >::iterator fit=tmpfiles.begin(); fit!=tmpfiles.end(); fit++) {
1313  std::string ext=ExtractExtension(*fit);
1314  std::string bas=ExtractBasename(*fit);
1315  std::string lfile=PrependDirectory(mFaudesDocTemp,*fit);
1316  std::string ffile=PrependDirectory(mFaudesDocTemp,bas+".fref");
1317  // skip non-lua
1318  if(ext!="lua") continue;
1319  // test for corresponding fref file
1320  std::string fref = ExtractBasename(*fit) + ".fref";
1321  if(tmpfiles.find(fref)!=tmpfiles.end()) continue;
1322  // process
1323  Lua2ref(lfile,ffile);
1324  // record (conditional for e.g. dstinstall, where no lua tutorials are generated)
1325  if(FileExists(ffile)) {
1326  docluasource.insert(ffile);
1327  tocsource.insert(ffile); // list of tutorials is required in toc
1328  frefbase.insert(bas);
1329  }
1330  }
1331 
1332  // convert/generate full generator images to fref (dest: doc/images)
1333  std::set< std::string > docimgsource;
1334  std::set< std::string > docrefsrcimg = ReadDirectory(PrependDirectory(mFaudesDocRefsrc,"images"));
1335  for(std::set < std::string >::iterator fit=docrefsrcimg.begin(); fit!=docrefsrcimg.end(); fit++) {
1336  std::string ext=ExtractExtension(*fit);
1337  std::string bas=ExtractBasename(*fit);
1338  std::string ffile=PrependDirectory(PrependDirectory(mFaudesDocRefsrc,"images"),*fit);
1339  if(ext!="fref") continue;
1340  docimgsource.insert(ffile);
1341  }
1342  std::set< std::string > imgfiles = ReadDirectory(mFaudesDocTemp);
1343  for(std::set < std::string >::iterator fit=imgfiles.begin(); fit!=imgfiles.end(); fit++) {
1344  std::string ext=ExtractExtension(*fit);
1345  std::string bas=ExtractBasename(*fit);
1346  std::string gfile=PrependDirectory(mFaudesDocTemp,*fit);
1347  std::string ffile=PrependDirectory(mFaudesDocTemp,bas+".fref");
1348  // skip non-gen
1349  if(ext!="gen") continue;
1350  // test whther we wrote that file
1351  if(mImageFiles.find(gfile)==mImageFiles.end()) continue;
1352  // process to fref
1353  Gen2ref(gfile,ffile);
1354  // record (conditional)
1355  if(FileExists(ffile))
1356  docimgsource.insert(ffile);
1357  }
1358 
1359 
1360  // compose toc
1361  std::string toccmd;
1362  for(std::set < std::string >::iterator fit=tocsource.begin(); fit!=tocsource.end(); fit++) {
1363  toccmd+= " " + *fit;
1364  }
1365  toccmd=mFaudesBinRef2html + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -toc " + toccmd
1366  + " " + mFaudesDocToc;
1367  std::cerr << "flxinstall: creating toc" << std::endl;
1368  if(std::system(toccmd.c_str())!=0) {
1369  std::cerr << "flxinstall: processing" << std::endl << toccmd << std::endl;
1370  std::cerr << "flxinstall: error setting up toc: ERROR." << std::endl;
1371  exit(1);
1372  }
1373  std::cerr << "flxinstall: creating toc: done" << std::endl;
1374 
1375 
1376  // process all pages to doc
1377  std::string doccmd;
1378  for(std::set < std::string >::iterator fit=docsource.begin(); fit!=docsource.end(); fit++) {
1379  doccmd += " " + *fit;
1380  }
1381  doccmd= mFaudesBinRef2html
1382  + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav
1383  + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc
1384  + doccmd + " " + mFaudesDoc;
1385  std::cerr << "flxinstall: processing doc base" << std::endl;
1386  if(std::system(doccmd.c_str())!=0) {
1387  std::cerr << "flxinstall: processing" << std::endl << doccmd << std::endl;
1388  std::cerr << "flxinstall: error while processing doc base: ERROR." << std::endl;
1389  exit(1);
1390  }
1391  std::cerr << "flxinstall: processing doc base: done" << std::endl;
1392 
1393  // process all pages to doc/reference
1394  std::string refcmd;
1395  for(std::set < std::string >::iterator fit=docrefsource.begin(); fit!=docrefsource.end(); fit++) {
1396  refcmd += " " + *fit;
1397  }
1398  refcmd= mFaudesBinRef2html
1399  + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav
1400  + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ "
1401  + refcmd + " " + mFaudesDocReference;
1402  std::cerr << "flxinstall: processing user reference" << std::endl;
1403  if(std::system(refcmd.c_str())!=0) {
1404  std::cerr << "flxinstall: processing" << std::endl << refcmd << std::endl;
1405  std::cerr << "flxinstall: error while processing user reference: ERROR." << std::endl;
1406  exit(1);
1407  }
1408  std::cerr << "flxinstall: processing user reference: done" << std::endl;
1409 
1410  // process all pages to doc/luafaudes
1411  if(mFaudesDocLuafaudes!="" && docluasource.size()>0) {
1412  std::string luacmd;
1413  for(std::set < std::string >::iterator fit=docluasource.begin(); fit!=docluasource.end(); fit++) {
1414  luacmd += " " + *fit;
1415  }
1416  luacmd= mFaudesBinRef2html
1417  + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav
1418  + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ "
1419  + luacmd + " " + mFaudesDocLuafaudes;
1420  std::cerr << "flxinstall: processing lua tutorial" << std::endl;
1421  if(std::system(luacmd.c_str())!=0) {
1422  std::cerr << "flxinstall: processing" << std::endl << luacmd << std::endl;
1423  std::cerr << "flxinstall: error while processing lua tutorial: ERROR." << std::endl;
1424  exit(1);
1425  }
1426  std::cerr << "flxinstall: processing lua tutorial: done" << std::endl;
1427  }
1428 
1429  // process all pages to doc/images/
1430  if(mFaudesDocImages!="" && docimgsource.size()>0) {
1431  std::cerr << "flxinstall: processing image files" << std::endl;
1432  // do at most 20 at the time (limit length of commandline)
1433  std::set < std::string >::iterator fit=docimgsource.begin();
1434  while(fit!=docimgsource.end()) {
1435  std::string imgcmd;
1436  for(; fit!=docimgsource.end(); fit++) {
1437  imgcmd += " " + *fit;
1438  if(imgcmd.length()>500) break;
1439  }
1440  imgcmd= mFaudesBinRef2html
1441  + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav
1442  + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ "
1443  + imgcmd + " " + mFaudesDocImages;
1444  if(std::system(imgcmd.c_str())!=0) {
1445  std::cerr << "flxinstall: processing" << std::endl << imgcmd << std::endl;
1446  std::cerr << "flxinstall: error while processing image files: ERROR." << std::endl;
1447  exit(1);
1448  }
1449  }
1450  std::cerr << "flxinstall: processing image files: done" << std::endl;
1451  }
1452 
1453 
1454  // copy index file: main index
1455  if(FileExists(PrependDirectory(mFaudesDocRefsrc,"faudes_about.fref"))) {
1456  std::string dst=PrependDirectory(mFaudesDoc,"index.html");
1457  std::string proccmd= mFaudesBinRef2html
1458  + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav
1459  + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ./ "
1460  + PrependDirectory(mFaudesDocRefsrc,"faudes_about.fref") + " " + dst;
1461  std::cerr << "flxinstall: fix html index " << std::endl;
1462  if(std::system(proccmd.c_str())!=0) {
1463  std::cerr << "flxinstall: error when processing index.html: ERROR." <<std::endl;
1464  exit(1);
1465  }
1466  }
1467 
1468  // copy index file: luafaudes
1470  std::string dst=PrependDirectory(mFaudesDocLuafaudes,"index.html");
1471  std::string proccmd= mFaudesBinRef2html
1472  + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav
1473  + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ "
1474  + PrependDirectory(mFaudesDocRefsrc,"luafaudes/faudes_luafaudes.fref") + " " + dst;
1475  std::cerr << "flxinstall: fix html index " << std::endl;
1476  if(std::system(proccmd.c_str())!=0) {
1477  std::cerr << "flxinstall: error when processing index.html: ERROR." <<std::endl;
1478  exit(1);
1479  }
1480  }
1481 
1482  // copy index file: reference
1484  std::string dst=PrependDirectory(mFaudesDocReference,"index.html");
1485  std::string proccmd= mFaudesBinRef2html
1486  + " -rti " + mFaudesDocRti + " -flx " + mFaudesBinLuaflx + " -cnav " + mFaudesDocNav
1487  + " -css " + mFaudesDocCss + " -inc " + mFaudesDocToc + " -rel ../ "
1488  + PrependDirectory(mFaudesDocRefsrc,"reference/reference_index.fref") + " " + dst;
1489  std::cerr << "flxinstall: fix html index " << std::endl;
1490  if(std::system(proccmd.c_str())!=0) {
1491  std::cerr << "flxinstall: error when processing index.html: ERROR." <<std::endl;
1492  exit(1);
1493  }
1494  }
1495 
1496  // clean tmp
1497  // (dont do so: keep frefs for dstinstall to extract index for qhc)
1498  /*
1499  for(std::set < std::string >::iterator fit=tmpfiles.begin(); fit!=tmpfiles.end(); fit++) {
1500  std::string dfile=PrependDirectory(mFaudesDocTemp,*fit);
1501  RemoveFile(*fit);
1502  }
1503  */
1504 
1505  std::cerr << "flxinstall: done" << std::endl;
1506 }
1507 
1508 
1509 // ******************************************************************
1510 // extract extension
1511 // ******************************************************************
1512 
1513 // control
1515 
1516  // test extension
1517  std::string ext=ExtractExtension(mSourceFile);
1518  std::string bas=ExtractBasename(mSourceFile);
1519  if(ext!="flx")
1520  usage_exit("extract must specify a *.flx source");
1521  // prepare to read
1523  Token btag;
1524  tr.ReadBegin("LuaExtension",btag);
1525  if(!btag.ExistsAttributeString("name")) {
1526  std::cerr << "flxinstall: lua-extension must have a name attribute " << tr.FileLine() << ": ERROR." << std::endl;
1527  exit(1);
1528  }
1529  mExtensionName=btag.AttributeStringValue("name");
1530  // scan for relevant sections
1531  while(!tr.Eos("LuaExtension")) {
1532  tr.Peek(btag);
1533  // skip tokens
1534  if(!btag.IsBegin()) {
1535  tr.Get(btag);
1536  continue;
1537  }
1538  // switch sections: fref
1539  if(btag.StringValue()=="ReferencePage") {
1540  // figure destination
1541  if(!btag.ExistsAttributeString("page")) {
1542  std::cerr << "flxinstall: skipping referencepage without page attribute" << std::endl;
1543  tr.ReadBegin(btag.StringValue());
1544  tr.ReadEnd(btag.StringValue());
1545  continue;
1546  }
1547  std::string page=mExtensionName + "_" + btag.AttributeStringValue("page") +".fref";
1548  std::transform(page.begin(), page.end(), page.begin(), tolower);
1549  std::string dstname= mTarget + faudes_pathsep() + page;
1550  std::cerr << "flxinstall: extracting reference page to \"" << dstname << "\"" << std::endl;
1551  // do copy incl outer tags
1552  TokenWriter tw(dstname,"ReferencePage");
1554  continue;
1555  }
1556  // switch sections: lua function
1557  if(btag.StringValue()=="LuaFunctionDefinition") {
1558  // figure destination
1559  if(!btag.ExistsAttributeString("name")) {
1560  std::cerr << "flxinstall: skipping lua function without name attribute" << std::endl;
1561  tr.ReadBegin(btag.StringValue());
1562  tr.ReadEnd(btag.StringValue());
1563  continue;
1564  }
1565  std::string name=btag.AttributeStringValue("name");
1566  size_t pos=name.find("::"); // test this construct for "xyz::"
1567  if(pos!=std::string::npos) name=name.substr(pos+2);
1568  name = name +".rti";
1569  std::transform(name.begin(), name.end(), name.begin(), tolower);
1570  std::string dstname= mTarget + faudes_pathsep() + name;
1571  std::cerr << "flxinstall: extracting lua function to \"" << dstname << "\"" << std::endl;
1572  // do copy incl outer tags
1573  TokenWriter tw(dstname,"LuaFunctionDefinition");
1574  InsertLuaFunction(tr,tw);
1575  continue;
1576  }
1577  // switch sections: image file
1578  if(btag.StringValue()=="ImageFile") {
1579  // figure destination
1580  if(!btag.ExistsAttributeString("name")) {
1581  std::cerr << "flxinstall: skipping image file without name attribute" << std::endl;
1582  tr.ReadBegin(btag.StringValue());
1583  tr.ReadEnd(btag.StringValue());
1584  continue;
1585  }
1586  std::string name= btag.AttributeStringValue("name");
1587  std::transform(name.begin(), name.end(), name.begin(), tolower);
1588  std::string dstname= mTarget + faudes_pathsep() + name;
1589  std::cerr << "flxinstall: extracting image file to \"" << dstname << "\"" << std::endl;
1590  TokenWriter tw(dstname);
1591  // read data
1592  tr.ReadBegin("ImageFile");
1593  Token data;
1594  tr.Get(data);
1595  if(!data.IsBinary()){
1596  }
1597  // copy to C++ stream
1598  std::fstream fsout;
1599  fsout.exceptions(std::ios::badbit|std::ios::failbit);
1600  try{
1601  fsout.open(dstname.c_str(), std::ios::out | std::ios::binary);
1602  fsout.write(data.StringValue().c_str(),data.StringValue().size());
1603  fsout.close();
1604  }
1605  catch (std::ios::failure&) {
1606  std::cerr << "flxinstall: file io error when writing \"" << dstname << "\"" << std::endl;
1607  }
1608  // done
1609  tr.ReadEnd("ImageFile");
1610  continue;
1611  }
1612  // switch sections: data file
1613  if(btag.StringValue()=="DataFile") {
1614  // figure destination
1615  if(!btag.ExistsAttributeString("name")) {
1616  std::cerr << "flxinstall: skipping data file without name attribute" << std::endl;
1617  tr.ReadBegin(btag.StringValue());
1618  tr.ReadEnd(btag.StringValue());
1619  continue;
1620  }
1621  std::string name= "data" + faudes_pathsep() + btag.AttributeStringValue("name");
1622  std::transform(name.begin(), name.end(), name.begin(), tolower);
1623  std::string dstname= mTarget + faudes_pathsep() + name;
1624  std::cerr << "flxinstall: extracting data file to \"" << dstname << "\"" << std::endl;
1625  // insist in data directiory
1626  MakeDirectory(mTarget,"data");
1627  TokenWriter tw(dstname);
1628  // read data
1629  tr.ReadBegin("DataFile");
1630  Token data;
1631  tr.Peek(data);
1632  // case 1: binary
1633  if(data.IsBinary()){
1634  tr.Get(data);
1635  // copy to C++ stream
1636  std::fstream fsout;
1637  fsout.exceptions(std::ios::badbit|std::ios::failbit);
1638  try{
1639  fsout.open(dstname.c_str(), std::ios::out | std::ios::binary);
1640  fsout.write(data.StringValue().c_str(),data.StringValue().size());
1641  fsout.close();
1642  } catch (std::ios::failure&) {
1643  std::cerr << "flxinstall: file io error when writing \"" << dstname << "\"" << std::endl;
1644  }
1645  }
1646  // case 2: token stream
1647  else if(data.IsBegin()){
1648  // copy to token writer excl outer tags
1649  InsertSection(tr,tw,data.StringValue());
1650  }
1651  // case 3: error
1652  else {
1653  std::cerr << "flxinstall: skipping invalid data " << tr.FileLine() << std::endl;
1654  }
1655  // read end tag
1656  tr.ReadEnd("DataFile");
1657  continue;
1658  }
1659  // switch sections: lua tutorial
1660  if(btag.StringValue()=="LuaTutorial") {
1661  // figure destination
1662  if(!btag.ExistsAttributeString("name")) {
1663  std::cerr << "flxinstall: skipping tutorial without name attribute" << std::endl;
1664  tr.ReadBegin(btag.StringValue());
1665  tr.ReadEnd(btag.StringValue());
1666  continue;
1667  }
1668  std::string name=btag.AttributeStringValue("name");
1669  std::transform(name.begin(), name.end(), name.begin(), tolower);
1670  std::string dstname= mTarget + faudes_pathsep() + name;
1671  std::cerr << "flxinstall: extracting tutorial to \"" << dstname << "\"" << std::endl;
1672  // do copy
1673  TokenWriter tw(dstname);
1674  InsertPlainLuaTutorial(tr,tw);
1675  continue;
1676  }
1677  // skip unknown
1678  tr.ReadBegin(btag.StringValue());
1679  tr.ReadEnd(btag.StringValue());
1680  }
1681  // done
1682  tr.ReadEnd("LuaExtension");
1683 }
1684 
1685 // ******************************************************************
1686 // run test cases
1687 // ******************************************************************
1688 
1689 // uses mSource for std flx
1690 
1692  // insist in luafaudes
1694  std::cerr << "flxinstall: cannot execute luafaudes" << std::endl;
1695  exit(1);
1696  }
1697  // read target directory to extract lua scripts
1698  std::set< std::string > allfiles = ReadDirectory(mTarget);
1699  std::set< std::string > luascripts;
1700  for(std::set < std::string >::iterator fit=allfiles.begin(); fit!=allfiles.end(); fit++)
1701  if(ExtractExtension(*fit)=="lua") luascripts.insert(*fit);
1702  // loop scripts
1703  for(std::set < std::string >::iterator fit=luascripts.begin(); fit!=luascripts.end(); fit++) {
1704  // build command
1705  std::string cmd = mFaudesBinLuafaudes + " -x " +mSourceFile + " " + *fit;
1706  // run
1707  std::cerr << "flxinstall: execute: " << cmd << std::endl;
1708  int sysret=std::system(cmd.c_str());
1709  if(sysret!=0) {
1710  std::cerr << "flxinstall: error while running lua script \"" << *fit << "\"" << std::endl;
1711  exit(1);
1712  }
1713  }
1714 
1715 
1716 }
1717 
1718 // ******************************************************************
1719 // command line ui
1720 // ******************************************************************
1721 
1722 
1723 int main(int argc, char *argv[]) {
1724 
1725  // local config
1726  bool doc=false;
1727  bool doi=false;
1728  bool dor=false;
1729  bool dox=false;
1730  bool dot=false;
1731 
1732  // min args
1733  if(argc < 2) usage_exit();
1734 
1735  // primitive commad line parsing
1736  int i;
1737  for(i=1; i<argc; i++) {
1738  std::string option(argv[i]);
1739  // overwrite doc
1740  if(option=="-tdoc") {
1741  i++; if(i>=argc) usage_exit();
1742  mFaudesDoc=argv[i];
1743  continue;
1744  }
1745  // overwrite bin
1746  if(option=="-tbin") {
1747  i++; if(i>=argc) usage_exit();
1748  mFaudesBin=argv[i];
1749  continue;
1750  }
1751  // overwrite rti
1752  if(option=="-trti") {
1753  i++; if(i>=argc) usage_exit();
1754  mFaudesDocRti=argv[i];
1755  continue;
1756  }
1757  // overwrite cnav
1758  if(option=="-tcnav") {
1759  i++; if(i>=argc) usage_exit();
1760  mFaudesDocNav=argv[i];
1761  continue;
1762  }
1763  // overwrite css
1764  if(option=="-tcss") {
1765  i++; if(i>=argc) usage_exit();
1766  mFaudesDocCss=argv[i];
1767  continue;
1768  }
1769  // target standalone
1770  if(option=="-tapp") {
1771  mFaudesStandalone = true;
1772  continue;
1773  }
1774  // mode: compile
1775  if(option=="-c") {
1776  i++; doc=true;
1777  break;
1778  }
1779  // mode: install
1780  if(option=="-i") {
1781  i++; doi=true;
1782  break;
1783  }
1784  // mode: remove
1785  if(option=="-r") {
1786  i++; dor=true;
1787  break;
1788  }
1789  // mode: extract
1790  if(option=="-x") {
1791  i++; dox=true;
1792  break;
1793  }
1794  // mode: test
1795  if(option=="-t") {
1796  i++; dot=true;
1797  break;
1798  }
1799  // option: help
1800  if((option=="-?") || (option=="--help")) {
1801  usage_exit();
1802  continue;
1803  }
1804  // option: unknown
1805  if(option.size()>1)
1806  if(option.at(0)=='-') {
1807  usage_exit("unknown option " + option);
1808  continue;
1809  }
1810  // must choose mode
1811  usage_exit("must set either -c, -i, -r, -x or -t mode" );
1812  }
1813 
1814  // create
1815  if(doc) {
1816  // figure source files
1817  for(;i<argc-1;i++) {
1818  mSourceFiles.insert(std::string(argv[i]));
1819  }
1820  // convenience: if its a directory, use all files inside
1821  if(mSourceFiles.size()==1) {
1822  std::set< std::string > srcfiles = ReadDirectory(std::string(argv[i-1]));
1823  srcfiles=EraseHiddenFiles(srcfiles);
1824  if(srcfiles.size()>0) {
1825  mSourceFiles.clear();
1826  for(std::set < std::string >::iterator fit=srcfiles.begin(); fit!=srcfiles.end(); fit++)
1827  mSourceFiles.insert(PrependDirectory(std::string(argv[i-1]),*fit));
1828  }
1829  }
1830  // have a target file
1831  if(!(i<argc))
1832  usage_exit("target *.flx-file not specified");
1833  // figure target file
1834  mTarget=std::string(argv[i]);
1835  // consistency: insist in .flx target
1836  if(mTarget!="-")
1837  if(ExtractExtension(mTarget)!="flx")
1838  usage_exit("target *.flx-file not specified");
1839  // doit
1841  exit(0);
1842  }
1843 
1844  // install
1845  if(doi) {
1846  // have at least one source
1847  if(!(i<argc-1))
1848  std::cerr << "flxinstall: no sources specified" << std::endl;
1849  // figure source files
1850  for(;i<argc-1;i++) {
1851  mSourceFiles.insert(std::string(argv[i]));
1852  }
1853  // convenience: if its a directory, use all files inside
1854  if(mSourceFiles.size()==1) {
1855  std::set< std::string > srcfiles = ReadDirectory(std::string(argv[i-1]));
1856  srcfiles=EraseHiddenFiles(srcfiles);
1857  if(srcfiles.size()>0) {
1858  mSourceFiles.clear();
1859  for(std::set < std::string >::iterator fit=srcfiles.begin(); fit!=srcfiles.end(); fit++)
1860  if(ExtractExtension(*fit)=="flx")
1861  mSourceFiles.insert(PrependDirectory(std::string(argv[i-1]),*fit));
1862  }
1863  }
1864  // insist in flx source
1865  for(std::set < std::string >::iterator fit=mSourceFiles.begin(); fit!=mSourceFiles.end(); fit++)
1866  if(ExtractExtension(*fit)!="flx")
1867  usage_exit("sources must be *.flx-files: "+ *fit);
1868  // figure target directory
1869  mTarget=std::string(argv[i]);
1870  TestFaudesTarget();
1871  // doit
1873  exit(0);
1874  }
1875 
1876  // remove
1877  if(dor) {
1878  // have at least one file
1879  if(i!=argc-1)
1880  usage_exit("target not specified");
1881  // figure target file
1882  mTarget=std::string(argv[i]);
1883  TestFaudesTarget();
1884  // doit
1887  exit(0);
1888  }
1889 
1890  // xtract
1891  if(dox) {
1892  // insist
1893  if(!(i<argc-1))
1894  usage_exit("source and destination must be specified");
1895  // figure source
1896  mSourceFile=std::string(argv[i++]);
1897  if(ExtractExtension(mSourceFile)!="flx")
1898  usage_exit("source must be an *.flx-file");
1899  // destination
1900  mTarget=std::string(argv[i++]);
1901  // test consistent args
1902  if((i<argc))
1903  usage_exit("too many arguments");
1904  // doit
1905  MakeDirectory(".",mTarget);
1907  exit(0);
1908  }
1909 
1910  // test
1911  if(dot) {
1912  // insist
1913  if(!(i<argc-1))
1914  usage_exit("source and temp dir must be specified");
1915  // figure source
1916  mSourceFile=std::string(argv[i++]);
1917  if(ExtractExtension(mSourceFile)!="flx")
1918  usage_exit("source must be an *.flx-file");
1919  // destination
1920  mTarget=std::string(argv[i++]);
1921  // test consistent args
1922  if((i<argc))
1923  usage_exit("too many arguments");
1924  // insist in target to be the current directory and empty
1925  if((mTarget != ".") && (mTarget != "./"))
1926  usage_exit("target must be \".\" or \"./\"");
1927  std::set< std::string > curdir = ReadDirectory(mTarget);
1928  if(curdir.size()!=0)
1929  usage_exit("target must be empty");
1930  // test for luafaudes (expects mFaudesBin)
1931  TestLuafaudes();
1932  // do extract and test
1934  RunTestCases();
1935  // done
1936  exit(0);
1937  }
1938 
1939  // error
1940  usage_exit();
1941 
1942  // never get here
1943  return 1;
1944 }
FAUDES_API const std::string & faudes_pathsep(void)
Definition: cfl_platform.h:185
Faudes exception class.
A TokenReader reads sequential tokens from a file or string.
std::string FileLine(void) const
Return "filename:line".
bool Eos(const std::string &rLabel)
Peek a token and check whether it ends the specified section.
void ReadVerbatim(const std::string &rLabel, std::string &rText)
Read verbatim text.
void ReadEnd(const std::string &rLabel)
Close the current section by matching the previous ReadBegin().
void Rewind(void)
Rewind stream.
void ReadSection(std::string &rSectionString)
Read XML section.
void ReadBegin(const std::string &rLabel)
Open a section by specified label.
bool Get(Token &token)
Get next token.
bool Peek(Token &token)
Peek next token.
std::istream * Streamp(void)
Access C++ stream.
std::string FileName(void) const
Access the filename.
A TokenWriter writes sequential tokens to a file, a string or stdout.
void WriteText(const std::string &rText)
Write text.
void WriteCharacterData(const std::string &rCharData)
Write character data.
void Write(Token &rToken)
Write next token.
void Endl(void)
Write endl separator.
std::ostream * Streamp(void)
Access C++ stream.
void WriteEnd(const std::string &rLabel)
Write end label.
void WriteBinary(const char *pData, long int len)
Write comment.
void WriteVerbatim(Token &rBeginTag, const std::string &rText)
Write verbatim text section.
void WriteBegin(const std::string &rLabel)
Write begin label.
Tokens model atomic data for stream IO.
Definition: cfl_token.h:53
bool IsBinary(void) const
Test token Type.
Definition: cfl_token.cpp:248
const std::string & StringValue(void) const
Get string value of a name token.
Definition: cfl_token.cpp:177
bool ExistsAttributeString(const std::string &name)
Test attibute existence.
Definition: cfl_token.cpp:355
bool IsBegin(void) const
Test token Type.
Definition: cfl_token.cpp:258
void SetBegin(const std::string &rName)
Initialize as Begin token.
Definition: cfl_token.cpp:91
void InsAttributeString(const std::string &name, const std::string &value)
Insert named attribute with string value.
Definition: cfl_token.cpp:309
const std::string & AttributeStringValue(const std::string &name)
Access attribute value.
Definition: cfl_token.cpp:385
Includes all libFAUDES headers, no plugins.
std::set< std::string > mReferencePages
Definition: flxinstall.cpp:78
int main(int argc, char *argv[])
void Lua2ref(const std::string &rLuaFile, const std::string &rRefFile="")
Definition: flxinstall.cpp:140
void CreateExtensionFile(void)
Definition: flxinstall.cpp:396
std::string mFaudesDocCss
Definition: flxinstall.cpp:93
std::string mFaudesBinRef2html
Definition: flxinstall.cpp:89
std::set< std::string > mLuaFunctions
Definition: flxinstall.cpp:81
std::string mXmlSeparator
Definition: flxinstall.cpp:70
void ExtractExtensionFile(void)
void XtractLuaTutorials(TokenReader &rTr, const std::string &rDstDir)
std::string mFaudesBinLua2ref
Definition: flxinstall.cpp:91
std::string mFaudesDocNav
Definition: flxinstall.cpp:95
std::string mFaudesBase
Definition: flxinstall.cpp:85
std::string mFaudesBinLuafaudes
Definition: flxinstall.cpp:87
std::string mFaudesDocRti
Definition: flxinstall.cpp:96
void XtractReferencePages(TokenReader &rTr, const std::string &rDstDir)
Definition: flxinstall.cpp:810
std::string mFaudesDocToc
Definition: flxinstall.cpp:94
void XtractLuaFunctions(TokenReader &rTr, TokenWriter &rTw)
std::string mFaudesDocTemp
Definition: flxinstall.cpp:101
std::string mFaudesDocReference
Definition: flxinstall.cpp:97
std::string mFaudesBin
Definition: flxinstall.cpp:86
void InsertSection(TokenReader &rTr, TokenWriter &rTw, const std::string &mLabel)
Definition: flxinstall.cpp:218
void InsertDataFile(TokenReader &rTr, TokenWriter &rTw)
Definition: flxinstall.cpp:354
void DefaultIndexPage(const std::string &rDstDir)
std::set< std::string > EraseHiddenFiles(const std::set< std::string > &src)
Definition: flxinstall.cpp:124
std::string mFaudesDocImages
Definition: flxinstall.cpp:99
void InsertReferencePage(TokenReader &rTr, TokenWriter &rTw, const std::string mSection="")
Definition: flxinstall.cpp:233
void MakeDirectory(const std::string &rPath, const std::string &rDir="")
Definition: flxinstall.cpp:110
std::set< std::string > mSourceFiles
Definition: flxinstall.cpp:74
std::string mTarget
Definition: flxinstall.cpp:76
void InsertImageFile(TokenReader &rTr, TokenWriter &rTw)
Definition: flxinstall.cpp:318
void InstallExtensionFiles(void)
void XtractImageGenFiles(TokenReader &rTr, const std::string &rDstDir)
Definition: flxinstall.cpp:951
void XtractImageFiles(TokenReader &rTr, const std::string &rDstDir)
Definition: flxinstall.cpp:883
void usage_exit(const std::string &rMessage="")
Definition: flxinstall.cpp:39
bool mFaudesStandalone
Definition: flxinstall.cpp:90
void TestLuafaudes(void)
Definition: flxinstall.cpp:640
std::string mSourceFile
Definition: flxinstall.cpp:75
std::string mFaudesBinLuaflx
Definition: flxinstall.cpp:88
void RunTestCases()
std::string mExtensionName
Definition: flxinstall.cpp:77
std::string mFaudesDocRefsrc
Definition: flxinstall.cpp:100
void TestFaudesTarget(void)
Definition: flxinstall.cpp:662
void Gen2ref(const std::string &rGenFile, const std::string &rRefFile="")
Definition: flxinstall.cpp:167
std::set< std::string > mImageFiles
Definition: flxinstall.cpp:80
std::set< std::string > mGeneratorFiles
Definition: flxinstall.cpp:79
void InsertLuaFunction(TokenReader &rTr, TokenWriter &rTw)
Definition: flxinstall.cpp:255
std::string mFaudesDoc
Definition: flxinstall.cpp:92
void InsertPlainLuaTutorial(TokenReader &rTr, TokenWriter &rTw)
Definition: flxinstall.cpp:273
void InsertLuaTutorial(TokenReader &rTr, TokenWriter &rTw)
Definition: flxinstall.cpp:282
std::string mFaudesDocLuafaudes
Definition: flxinstall.cpp:98
libFAUDES resides within the namespace faudes.
std::string VersionString()
Return FAUDES_VERSION as std::string.
Definition: cfl_helper.cpp:131
std::string ExtractDirectory(const std::string &rFullPath)
Extract directory from full path.
Definition: cfl_helper.cpp:262
bool RemoveFile(const std::string &rFileName)
Delete a file.
Definition: cfl_helper.cpp:256
std::string ExtractExtension(const std::string &rFullPath)
Extract file name from full path.
Definition: cfl_helper.cpp:294
std::string ExtractBasename(const std::string &rFullPath)
Extract file name from full path.
Definition: cfl_helper.cpp:280
bool FileCopy(const std::string &rFromFile, const std::string &rToFile)
Copy file.
Definition: cfl_helper.cpp:385
std::string PrependDirectory(const std::string &rDirectory, const std::string &rFileName)
Construct full path from directory and filename.
Definition: cfl_helper.cpp:309
std::string ExtractFilename(const std::string &rFullPath)
Extract file name from full path.
Definition: cfl_helper.cpp:271
bool FileDelete(const std::string &rFilename)
Delete file.
Definition: cfl_helper.cpp:380
std::set< std::string > ReadDirectory(const std::string &rDirectory)
Read the contents of the specified directors.
Definition: cfl_helper.cpp:336
bool DirectoryExists(const std::string &rDirectory)
Test existence of directory.
Definition: cfl_helper.cpp:320
bool FileExists(const std::string &rFilename)
Test existence of file.
Definition: cfl_helper.cpp:373

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen