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

libFAUDES 2.32f --- 2024.12.22 --- c++ api documentaion by doxygen