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