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

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen