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

libFAUDES 2.34e --- 2026.03.16 --- c++ api documentaion by doxygen