CompileDES 3.14
Executable-Code Generation from Synchronised libFAUDES Automata
cgp_plcoxml.cpp
Go to the documentation of this file.
1
3/*
4 FAU Discrete Event Systems Library (libFAUDES)
5
6 Copyright (C) 2010, 2016, 2017 Thomas Moor
7
8*/
9
10// my includes
11#include "cgp_plcoxml.h"
12#include <ctime>
13
14
15/*
16******************************************************************
17******************************************************************
18******************************************************************
19
20PlcoxmlCodeGenerator implementation --- class
21
22******************************************************************
23******************************************************************
24******************************************************************
25*/
26
27
28// Register derived class
30
31
32// PlcoxmlCodeGenerator(void)
34 FD_DCG("PlcoxmlCodeGenerator(" << this << ")::PlcoxmlCodeGenerator()");
35}
36
37
38// PlcoxmlCodeGenerator(void)
40 FD_DCG("PlcoxmlCodeGenerator(" << this << ")::~PlcoxmlCodeGenerator()");
41}
42
43
44// clear
46 FD_DCG("PlcoxmlCodeGenerator::Clear()");
47 // call base
49 // my output format defaults
50 mIecSchemeVersion="v2.01";
51 mIecToolVendor="FGDES/LRT";
55 mIecTextElement="cdata";
56 // my code defaults
58}
59
60//DoReadTargetConfiguration(rTr)
62 FD_DCG("PlcoxmlCodeGenerator::DoReadTargetConfiguration()");
63 // base
65 // Plcoxml option
66 Token token;
67 if(rTr.ExistsBegin("IecSchemeVersion")) {
68 rTr.ReadBegin("IecSchemeVersion",token);
69 mIecSchemeVersion= token.AttributeStringValue("val");
70 rTr.ReadEnd("IecSchemeVersion");
71 }
72 if(rTr.ExistsBegin("IecToolVendor")) {
73 rTr.ReadBegin("IecToolVendor",token);
74 mIecToolVendor= token.AttributeStringValue("val");
75 rTr.ReadEnd("IecToolVendor");
76 }
77 if(rTr.ExistsBegin("IecContentAuthor")) {
78 rTr.ReadBegin("IecContentAuthor",token);
79 mIecContentAuthor= token.AttributeStringValue("val");
80 rTr.ReadEnd("IecContentAuthor");
81 }
82 if(rTr.ExistsBegin("IecContentOrganization")) {
83 rTr.ReadBegin("IecContenetOrganization",token);
84 mIecContentOrganization= token.AttributeStringValue("val");
85 rTr.ReadEnd("IecContentOrganization");
86 }
87 if(rTr.ExistsBegin("IecContentVersion")) {
88 rTr.ReadBegin("IecContentVersion",token);
89 mIecContentVersion= token.AttributeStringValue("val");
90 rTr.ReadEnd("IecContentVersion");
91 }
92 if(rTr.ExistsBegin("IecTextElement")) {
93 rTr.ReadBegin("IecTextElement",token);
94 mIecTextElement= token.AttributeStringValue("val");
95 rTr.ReadEnd("IecTextElement");
96 }
97}
98
99//DoWriteTargetConfiguration(rTw)
101 FD_DCG("PlcoxmlCodeGenerator::DoWriteTargetConfiguration()");
102 // base
104 // iec code option
105 Token token;
106 token.SetEmpty("IecSchemeVersion");
107 token.InsAttributeString("val",mIecSchemeVersion);
108 rTw.Write(token);
109 token.SetEmpty("IecToolVendor");
110 token.InsAttributeString("val",mIecToolVendor);
111 rTw.Write(token);
112 if(mIecContentAuthor.size()>0) {
113 token.SetEmpty("IecContentAuthor");
114 token.InsAttributeString("val",mIecContentAuthor);
115 rTw.Write(token);
116 }
117 if(mIecContentOrganization.size()>0) {
118 token.SetEmpty("IecContentCompany");
119 token.InsAttributeString("val",mIecContentOrganization);
120 }
121 if(mIecContentVersion.size()>0) {
122 rTw.Write(token);
123 token.SetEmpty("IecContentVersion");
124 token.InsAttributeString("val",mIecContentVersion);
125 }
126 if(mIecTextElement.size()>0) {
127 rTw.Write(token);
128 token.SetEmpty("IecTextElement");
129 token.InsAttributeString("val",mIecTextElement);
130 rTw.Write(token);
131 }
132}
133
134
135
136/*
137******************************************************************
138******************************************************************
139******************************************************************
140
141PlcoxmlGenerator implementation --- code organisation
142
143******************************************************************
144******************************************************************
145******************************************************************
146*/
147
148// DoGenerate()
150 // report on missconfig
151 if((mIecSchemeVersion!="v2.01") && (mIecSchemeVersion!="v1.01"))
152 FCG_ERR("PlcoxmlCodeGenerator::DoGenerate(): xml scheme \"" << mIecSchemeVersion << "\" not supported");
153 if((mIecTextElement !="xhtml") && (mIecTextElement !="cdata") && (mIecTextElement !=""))
154 FCG_ERR("PlcoxmlCodeGenerator::DoGenerate(): xml text element \"" << mIecTextElement << "\" not supported");
155 // report on missconfig
156 if(mName.size()==0)
157 FCG_ERR("PlcoxmlCodeGenerator::DoGenerate(): xml format requires a project name");
158 // report on missconfig
159 if(mLiteralCyclic.size()!=0)
160 FCG_ERR("PlcoxmlCodeGenerator::DoGenerate(): literal insert to cyclic function not supported by this target");
161 if(mLiteralPrepend.size()!=0)
162 FCG_ERR("PlcoxmlCodeGenerator::DoGenerate(): literal prepend not supported by this target");
163 if(mLiteralAppend.size()!=0)
164 FCG_ERR("PlcoxmlCodeGenerator::DoGenerate(): literal append not supported by this target");
165 // cut and paste from base
166 mBitarrays.clear();
167 // set up time string
168 time_t now_time;
169 struct tm* now_tm;
170 time (&now_time);
171 now_tm = localtime(&now_time);
172 char now_str[25];
173 snprintf(now_str,24,"%4d-%02d-%02dT%02d:%02d:%02d",now_tm->tm_year+1900,now_tm->tm_mon+1,now_tm->tm_mday,now_tm->tm_hour,now_tm->tm_min,now_tm->tm_sec);
174 std::string datestr(now_str);
175 std::string verstr=COMPILEDES_VERSION;
176 // doit: produce XML encoding
177 Output() << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
178 // doit: open XML project element
179 if(mIecSchemeVersion=="v1.01") {
180 Output() << "<project" << std::endl;
181 Output() << " xmlns=\"http://www.plcopen.org/xml/tc6.xsd\"" << std::endl;
182 Output() << " xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"" << std::endl;
183 Output() << " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" << std::endl;
184 Output() << " xsi:schemaLocation=\"http://www.plcopen.org/xml/tc6.xsd http://www.plcopen.org/xml/tc6.xsd\" >" << std::endl;
185 } else if(mIecSchemeVersion=="v2.01") {
186 Output() << "<project" << std::endl;
187 Output() << " xmlns=\"http://www.plcopen.org/xml/tc6_0201\"" << std::endl;
188 Output() << " xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"" << std::endl;
189 Output() << " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" << std::endl;
190 Output() << " xsi:schemaLocation=\"http://www.plcopen.org/xml/tc6_0201 http://www.plcopen.org/xml/tc6.xsd\" >" << std::endl;
191 } else {
192 Output() << "<project>" << std::endl;
193 }
194 // doit: empty XML fileHeader element
195 Output() << "<fileHeader" << std::endl;
196 Output() << " companyName=\"" << mIecToolVendor << "\"" << std::endl;
197 Output() << " creationDateTime=\"" << datestr << "\"" << std::endl;
198 Output() << " productName=\"CompileDES\"" << std::endl;
199 Output() << " productVersion=\"" << verstr << "\" />" << std::endl;
200 // doit: open XML contentHeader element
201 Output() << "<contentHeader" << std::endl;
202 Output() << " name=\"" << mName << "\"";
203 if(mIecContentAuthor.size()>0) Output() << std::endl << " author=\"" << mIecContentAuthor << "\"";
204 if(mIecContentOrganization.size()>0) Output() << std::endl << " organization=\"" << mIecContentOrganization << "\"";
205 if(mIecContentVersion.size()>0) Output() << std::endl << " version=\"" << mIecContentVersion << "\"";
206 Output() << " >" << std::endl;
207 // doit: complete XML coordinateInfo element
208 Output() << " <coordinateInfo>" << std::endl;
209 Output() << " <fbd><scaling x=\"1\" y=\"1\"/></fbd>" << std::endl;
210 Output() << " <ld><scaling x=\"1\" y=\"1\"/></ld>" << std::endl;
211 Output() << " <sfc><scaling x=\"1\" y=\"1\"/></sfc>" << std::endl;
212 Output() << " </coordinateInfo>" << std::endl;
213 // doit: close XML header element
214 Output() << "</contentHeader>" << std::endl;
215 // doit: open XML types element
216 Output() << "<types>" << std::endl;
217 // doit: empty XML dataTypes element
218 Output() << "<dataTypes />" << std::endl;
219 // doit: open XML pous element
220 Output() << "<pous>" << std::endl;
223 Output() << "</pous>" << std::endl;
224 Output() << "</types>" << std::endl;
225 // doit: void XML instances element
226 Output() << "<instances>" << std::endl;
227 Output() << " <configurations />" << std::endl;
228 Output() << "</instances>" << std::endl;
229 // doit: close XML open elements
230 Output() << "</project>" << std::endl;
231}
232
234 // open XML my function block element
235 Output() << "<pou name=\"" << mPrefix << "cyclic_fb" << "\" pouType=\"functionBlock\">" << std::endl;
236 // open XML my interface element
237 Output() << "<interface>" << std::endl;
238 IndentInc();
240 IndentDec();
241 // close XML interface element
242 Output() << "</interface>" << std::endl;
243 // open XML my body element
244 Output() << "<body>" << std::endl;
245 Output() << "<ST>" << std::endl;
246 XmlBeginPlainText();
247 Output() << std::endl;
249 XmlEndPlainText();
250 Output() << std::endl;
251 // close XML open elements
252 Output() << "</ST>" << std::endl;
253 Output() << "</body>" << std::endl;
254 Output() << "</pou>" << std::endl;
255}
256
257
258// code blocks: cyclic function block (interface)
260 // have counts
261 int pio = CountImportPhysicalIo();
262 int sio = CountImportSymbolicIo();
263 // interface: arguments
264 MuteComments(true);
265 MuteVspace(true);
266 Output() << "<inputVars retain=\"false\">" << std::endl;
267 IndentInc();
268 DeclareReset();
269 IndentDec();
270 Output() << "</inputVars>" << std::endl;
271 MuteComments(false);
272 MuteVspace(false);
273 // interface: return value
274 MuteComments(true);
275 MuteVspace(true);
276 Output() << "<outputVars retain=\"false\">" << std::endl;
277 IndentInc();
282 IndentDec();
283 Output() << "</outputVars>" << std::endl;
284 MuteComments(false);
285 MuteVspace(false);
286 // interface: local variables
287 MuteComments(true);
288 MuteVspace(true);
289 Output() << "<localVars retain=\"false\">" << std::endl;
290 IndentInc();
296 DeclareAux();
299 if((mIecDeclarePhysical=="VAR") && (pio>0))
302 IndentDec();
303 Output() << "</localVars>" << std::endl;
304 MuteVspace(false);
305 MuteComments(false);
306 // interface: extern variables
307 MuteComments(true);
308 MuteVspace(true);
309 if(mIecDeclarePhysical=="VAR_EXTERNAL") {
310 if(pio+sio>0) {
311 Output() << "<externalVars>" << std::endl;
312 IndentInc();
313 if(sio>0) DeclareImportSymbolicIo();
314 if(pio>0) DeclareImportPhysicalIo();
315 IndentDec();
316 Output() << "</externalVars>" << std::endl;
317 }
318 } else {
319 if(sio>0) {
320 Output() << "<externalVars>" << std::endl;
321 IndentInc();
323 IndentDec();
324 Output() << "</externalVars>" << std::endl;
325 }
326 }
327 MuteVspace(false);
328 MuteComments(false);
329}
330
331
332// code blocks: cyclic function block (body)
334 Comment("************************************************");
335 Comment("CodeGenerator: Target IEC 61131 Structured Text ");
336 Comment("************************************************");
337 LineFeed(2);
338 Comment(std::string("CompileDES ") + VersionString());
339 Comment(std::string("Configuration: ") + Name());
340 LineFeed(2+1);
345 LineFeed(1+2);
346 Comment("************************************************");
347 Comment("CodeGenerator: Generated Code Ends Here ");
348 Comment("************************************************");
349}
350
351
354 for(;lit!=LinesEnd();++lit) {
355 std::string lineaddr= lit->second.mAddress;
356 if(lineaddr.size()<1) continue; // paranoia
357 if(lineaddr.at(0)=='%') {
358 Output() << "<variable name=\"\" address=\"" << lineaddr << "\">";
359 LineFeed();
360 IndentInc();
361 Output() << "<type> <BOOL /> </type>";
362 LineFeed();
363 XmlDocumentation("physical input");
364 LineFeed();
365 IndentDec();
366 Output() << "</variable>";
367 LineFeed();
368 }
369 }
371 for(;ait!=ActionAddressesEnd();++ait) {
372 if(!ait->second.mSetClr) continue;
373 std::string actaddr= ait->second.mAddress;
374 if(actaddr.size()<1) continue; // paranoia
375 if(actaddr.at(0)=='%') {
376 Output() << "<variable name=\"\" address=\"" << actaddr << "\">";
377 LineFeed();
378 IndentInc();
379 Output() << "<type> <BOOL /> </type>";
380 LineFeed();
381 XmlDocumentation("physical output");
382 LineFeed();
383 IndentDec();
384 Output() << "</variable>";
385 LineFeed();
386 }
387 }
388}
389
390
391// code blocks: functions to host lookup tables
393 if(mEventNameLookup) {
394 // open XML my function block element
395 Output() << "<pou name=\"" << mPrefix << "event_lookup_f" << "\" pouType=\"function\">" << std::endl;
396 // open XML my interface element
397 Output() << "<interface>" << std::endl;
398 IndentInc();
399 // interface: return type
400 Output() << "<returnType> <string /> </returnType>" << std::endl;
401 // interface: argument
402 Output() << "<inputVars retain=\"false\">" << std::endl;
403 Output() << " <variable name=\"IDX\">" << std::endl;
404 Output() << " <type> <" << mIntegerType << " /> </type>" << std::endl;
405 Output() << " ";
406 XmlDocumentation("event index");
407 Output() << std::endl;
408 Output() << " </variable>" << std::endl;
409 Output() << "</inputVars>" << std::endl;
410 // interface: local variables
411 MuteComments(true);
412 MuteVspace(true);
413 Output() << "<localVars retain=\"false\" constant=\"true\">" << std::endl;
414 IndentInc();
416 IndentDec();
417 Output() << "</localVars>" << std::endl;
418 MuteVspace(false);
419 MuteComments(false);
420 IndentDec();
421 // close XML interface element
422 Output() << "</interface>" << std::endl;
423 // open XML my body element
424 Output() << "<body>" << std::endl;
425 Output() << "<ST>" << std::endl;
426 XmlBeginPlainText();
427 Output() << mPrefix <<"event_lookup_f" << " := " << mPrefix << "event_lookup[IDX]" << ";";
428 Output() << std::endl;
429 XmlEndPlainText();
430 // close XML open elements
431 Output() << "</ST>" << std::endl;
432 Output() << "</body>" << std::endl;
433 Output() << "</pou>" << std::endl;
434 }
435 if(mStateNameLookup) {
436 // open XML my function block element
437 Output() << "<pou name=\"" << mPrefix << "state_lookup_f" << "\" pouType=\"function\">" << std::endl;
438 // open XML my interface element
439 Output() << "<interface>" << std::endl;
440 IndentInc();
441 // interface: return type
442 Output() << "<returnType> <string /> </returnType>" << std::endl;
443 // interface: argument
444 Output() << "<inputVars retain=\"false\">" << std::endl;
445 Output() << " <variable name=\"GID\">" << std::endl;
446 Output() << " <type> <" << mIntegerType << " /> </type>" << std::endl;
447 Output() << " ";
448 XmlDocumentation("generator id");
449 Output() << std::endl;
450 Output() << " </variable>" << std::endl;
451 Output() << " <variable name=\"IDX\">" << std::endl;
452 Output() << " <type> <" << mIntegerType << " /> </type>" << std::endl;
453 Output() << " ";
454 XmlDocumentation("state index");
455 Output() << std::endl;
456 Output() << " </variable>" << std::endl;
457 Output() << "</inputVars>" << std::endl;
458 // interface: local variables
459 MuteComments(true);
460 MuteVspace(true);
461 Output() << "<localVars retain=\"false\" constant=\"true\">" << std::endl;
462 IndentInc();
464 IndentDec();
465 Output() << "</localVars>" << std::endl;
466 MuteVspace(false);
467 MuteComments(false);
468 IndentDec();
469 // close XML interface element
470 Output() << "</interface>" << std::endl;
471 // open XML my body element
472 Output() << "<body>" << std::endl;
473 Output() << "<ST>" << std::endl;
474 XmlBeginPlainText();
475 Output() << mPrefix << "state_lookup_f:='';";
476 LineFeed();
477 Output() << "CASE GID OF";
478 LineFeed();
479 for(size_t gid=0; gid<Size(); ++gid) {
480 if(!mHasStateNames[gid]) continue;
481 Output() << ToStringInteger(gid) << ": "
482 << mPrefix <<"state_lookup_f" << " := " << mPrefix << "state_lookup_" << ToStringInteger(gid) << "[IDX]" << ";";
483 LineFeed();
484 }
485 Output() << "END_CASE;";
486 LineFeed();
487 Output() << "IF LEN(" << mPrefix << "state_lookup_f) = 0 THEN";
488 LineFeed();
489 Output() << " " << mPrefix <<"state_lookup_f" << " := CONCAT('s'," << mIntegerType << "_TO_STRING(IDX))" << ";";
490 LineFeed();
491 Output() << "END_IF;";
492 Output() << std::endl;
493 XmlEndPlainText();
494 // close XML open elements
495 Output() << "</ST>" << std::endl;
496 Output() << "</body>" << std::endl;
497 Output() << "</pou>" << std::endl;
498 }
499}
500
501
502/*
503******************************************************************
504******************************************************************
505******************************************************************
506
507PlcoxmlCodeGenerator implementation --- code primitives
508
509******************************************************************
510******************************************************************
511******************************************************************
512*/
513
514// switch to/from plain text
515void PlcoxmlCodeGenerator::XmlBeginPlainText() {
516 if(mIecTextElement=="xhtml") {
517 Output() << "<xhtml xmlns=\"http://www.w3.org/1999/xhtml\">";
518 XmlTextEscape(true);
519 } else if(mIecTextElement=="cdata") {
520 Output() << "<![CDATA[";
521 XmlCdataEscape(true);
522 } else {
523 XmlTextEscape(true);
524 }
525};
526
527// switch to/from plain text
528void PlcoxmlCodeGenerator::XmlEndPlainText() {
529 if(mIecTextElement=="xhtml") {
530 XmlTextEscape(false);
531 Output() << "</xhtml>";
532 } else if(mIecTextElement=="cdata") {
533 XmlCdataEscape(false);
534 Output() << "]]>";
535 } else {
536 XmlTextEscape(false);
537 }
538};
539
540
541// switch to/from plain text
542void PlcoxmlCodeGenerator::XmlDocumentation(const std::string& text) {
543 Output() << "<documentation>";
544 XmlBeginPlainText();
545 Output() << text;
546 XmlEndPlainText();
547 Output() << "</documentation>";
548};
549
550// generate code: declare template
551void PlcoxmlCodeGenerator::VariableDeclare(const std::string& laddr, const std::string& ltype){
552 Output() << "<variable name=\"" << laddr << "\">";
553 LineFeed();
554 IndentInc();
555 if((ltype == mIntegerType) || (ltype == mWordType) || (ltype == "BOOL") || (ltype == "TIME")) {
556 Output() << "<type> <" << ltype << " /> </type>";
557 } else if((ltype == "TON") || (ltype == "STRING")) {
558 Output() << "<type> <derived name=\"" << ltype << "\" /> </type>";
559 } else {
560 FCG_ERR("PlcoxmlCodeGenerator::VariableDeclare(): unsupported type [" << ltype << "]");
561 }
562 LineFeed();
563 XmlDocumentation(RecentComment());
564 LineFeed();
565 IndentDec();
566 Output() << "</variable>";
567 LineFeed();
568}
569
570// generate code: declare template with initialiser
571void PlcoxmlCodeGenerator::VariableDeclare(const std::string& laddr, const std::string& ltype, const std::string& lval){
572 Output() << "<variable name=\"" << laddr << "\">";
573 LineFeed();
574 IndentInc();
575 if((ltype == mIntegerType) || (ltype == mWordType) || (ltype == "BOOL") || (ltype == "TIME")) {
576 Output() << "<type> <" << ltype << " /> </type>";
577 } else {
578 FCG_ERR("PlcoxmlCodeGenerator::VariableDeclare(): unsupported type [" << ltype << "]");
579 }
580 LineFeed();
581 Output() << "<initialValue> <simpleValue value=\"" << lval << "\" /> </initialValue>";
582 LineFeed();
583 XmlDocumentation(RecentComment());
584 LineFeed();
585 IndentDec();
586 Output() << "</variable>";
587 LineFeed();
588}
589
590
591
592// generate code: const-int-array
593void PlcoxmlCodeGenerator::CintarrayDeclare(const AA& address, int offset, const std::vector<int>& val) {
594 if(val.size()==0) {
595 FCG_ERR("PlcoxmlCodeGenerator::Cintarray(): ignoring empty const vector");
596 return;
597 }
598 if(val.size()+offset >= (1ULL << (mIntegerSize-1))) {
599 FCG_ERR("PlcoxmlCodeGenerator::Cintarray(): const vector exceeds addres range");
600 return;
601 }
602 Output() << "<variable name=\"" << TargetAddress(address) << "\">";
603 LineFeed();
604 IndentInc();
605 Output() << "<type>";
606 LineFeed();
607 Output() << " <array>";
608 LineFeed();
609 Output() << " <dimension lower=\"" << offset << "\" upper=\"" << val.size()+offset-1 << "\" />";
610 LineFeed();
611 Output() << " <baseType> <" << mIntegerType << " /> </baseType>";
612 LineFeed();
613 Output() << " </array>";
614 LineFeed();
615 Output() << "</type>";
616 LineFeed();
617 Output() << "<initialValue> ";
618 LineFeed();
619 Output() << " <arrayValue> ";
620 LineFeed();
621 for(size_t i=0; i<val.size(); ++i) {
622 Output() << " <value> <simpleValue value=\"" << IntegerConstant(val[i]) << "\" /> </value>";
623 LineFeed();
624 }
625 Output() << " </arrayValue> ";
626 LineFeed();
627 Output() << "</initialValue> ";
628 LineFeed();
629 XmlDocumentation(RecentComment());
630 LineFeed();
631 IndentDec();
632 Output() << "</variable>";
633 LineFeed();
634}
635
636// generate code: const-word-array
637void PlcoxmlCodeGenerator::CwordarrayDeclare(const AA& address, int offset, const std::vector<word_t>& val) {
638 if(val.size()==0) {
639 FCG_ERR("PlcoxmlCodeGenerator::Cwordarray(): ignoring empty const vector");
640 return;
641 }
642 if(val.size()+offset >= (1ULL << (mIntegerSize-1))) {
643 FCG_ERR("PlcoxmlCodeGenerator::Cwordarray(): const vector exceeds addres range");
644 return;
645 }
646 Output() << "<variable name=\"" << TargetAddress(address) << "\">";
647 LineFeed();
648 IndentInc();
649 Output() << "<type>";
650 LineFeed();
651 Output() << " <array>";
652 LineFeed();
653 Output() << " <dimension lower=\"" << offset << "\" upper=\"" << val.size()+offset-1 << "\" />";
654 LineFeed();
655 Output() << " <baseType> <" << mWordType << " /> </baseType>";
656 LineFeed();
657 Output() << " </array>";
658 LineFeed();
659 Output() << "</type>";
660 LineFeed();
661 Output() << "<initialValue> ";
662 LineFeed();
663 Output() << " <arrayValue> ";
664 LineFeed();
665 for(size_t i=0; i<val.size(); ++i) {
666 Output() << " <value> <simpleValue value=\"" << WordConstant(val[i]) << "\" /> </value>";
667 LineFeed();
668 }
669 Output() << " </arrayValue> ";
670 LineFeed();
671 Output() << "</initialValue> ";
672 LineFeed();
673 XmlDocumentation(RecentComment());
674 LineFeed();
675 IndentDec();
676 Output() << "</variable>";
677 LineFeed();
678}
679
680
681// generate code: const-str-array
682void PlcoxmlCodeGenerator::CstrarrayDeclare(const AA& address, int offset, const std::vector<std::string>& val) {
683 if(val.size()==0) {
684 FCG_ERR("PlcoxmlCodeGenerator::Cstrarray(): ignoring empty const vector");
685 return;
686 }
687 if(val.size()+offset >= (1ULL << (mIntegerSize-1))) {
688 FCG_ERR("PlcoxmlCodeGenerator::Cstrarray(): const vector exceeds address range");
689 return;
690 }
691 // figure string size
692 size_t len=0;
693 for(size_t i=0; i<val.size(); ++i)
694 if(val[i].size()>len) len=val[i].size();
695 // generate code
696 Output() << "<variable name=\"" << TargetAddress(address) << "\">";
697 LineFeed();
698 IndentInc();
699 Output() << "<type>";
700 LineFeed();
701 Output() << " <array>";
702 LineFeed();
703 Output() << " <dimension lower=\"" << offset << "\" upper=\"" << val.size()+offset-1 << "\" />";
704 LineFeed();
705 Output() << " <baseType> <string length=\"" << ToStringInteger(len) << "\" /> </baseType>";
706 LineFeed();
707 Output() << " </array>";
708 LineFeed();
709 Output() << "</type>";
710 LineFeed();
711 Output() << "<initialValue> ";
712 LineFeed();
713 Output() << " <arrayValue> ";
714 LineFeed();
715 for(size_t i=0; i<val.size(); ++i) {
716 Output() << " <value> <simpleValue value=\"";
717 XmlTextEscape(true); // use Xml escape
718 std::string dat=StringConstant(val[i]); // use iec string escape
719 // dat = dat.substr(1,dat.size()-2); // strip delimiting single quotes [codesys does not like this]
720 Output() << dat;
721 XmlTextEscape(false);
722 Output()<< "\" /> </value>";
723 LineFeed();
724 }
725 Output() << " </arrayValue> ";
726 LineFeed();
727 Output() << "</initialValue> ";
728 LineFeed();
729 XmlDocumentation(RecentComment());
730 LineFeed();
731 IndentDec();
732 Output() << "</variable>";
733 LineFeed();
734}
735
736// generate code: int-array
737void PlcoxmlCodeGenerator::IntarrayDeclare(const AA& address, int offset, const std::vector<int>& val) {
738 CintarrayDeclare(address,offset,val);
739}
740
741// generate code: int-array
742void PlcoxmlCodeGenerator::IntarrayDeclare(const AA& address, int offset, int len) {
743 if(len==0) {
744 FCG_ERR("PlcoxmlCodeGenerator::Intarray(): ignoring empty const vector");
745 return;
746 }
747 if(len+offset >= (1LL << (mIntegerSize-1))) {
748 FCG_ERR("PlcoxmlCodeGenerator::Intarray(): const vector exceeds addres range");
749 return;
750 }
751 Output() << "<variable name=\"" << TargetAddress(address) << "\">";
752 LineFeed();
753 IndentInc();
754 Output() << "<type>";
755 LineFeed();
756 Output() << " <array>";
757 LineFeed();
758 Output() << " <dimension lower=\"" << offset << "\" upper=\"" << len+offset-1 << "\" />";
759 LineFeed();
760 Output() << " <baseType> <" << mIntegerType << " /> </baseType>";
761 LineFeed();
762 Output() << " </array>";
763 LineFeed();
764 Output() << "</type>";
765 LineFeed();
766 XmlDocumentation(RecentComment());
767 LineFeed();
768 IndentDec();
769 Output() << "</variable>";
770 LineFeed();
771}
772
773
774// generate code: word-array
775void PlcoxmlCodeGenerator::WordarrayDeclare(const AA& address, int offset, const std::vector<word_t>& val) {
776 CwordarrayDeclare(address,offset,val);
777}
778
779// generate code: word-array
780void PlcoxmlCodeGenerator::WordarrayDeclare(const AA& address, int offset, int len) {
781 if(len==0) {
782 FCG_ERR("PlcoxmlCodeGenerator::Wordarray(): ignoring empty const vector");
783 return;
784 }
785 if(len+offset >= (1LL << (mIntegerSize-1))) {
786 FCG_ERR("PlcoxmlCodeGenerator::Wordarray(): const vector exceeds addres range");
787 return;
788 }
789 Output() << "<variable name=\"" << TargetAddress(address) << "\">";
790 LineFeed();
791 IndentInc();
792 Output() << "<type>";
793 LineFeed();
794 Output() << " <array>";
795 LineFeed();
796 Output() << " <dimension lower=\"" << offset << "\" upper=\"" << len+offset-1 << "\" />";
797 LineFeed();
798 Output() << " <baseType> <" << mWordType << " /> </baseType>";
799 LineFeed();
800 Output() << " </array>";
801 LineFeed();
802 Output() << "</type>";
803 LineFeed();
804 XmlDocumentation(RecentComment());
805 LineFeed();
806 IndentDec();
807 Output() << "</variable>";
808 LineFeed();
809}
810
811
#define FAUDES_REGISTERCODEGENERATOR(ftype, ctype)
Class registration macro.
Code-generator PlcOpen XML (IEC 61131-3 ST)
virtual void LineFeed(int lines=1)
LineFeed (convenience support for derived classes)
virtual void XmlCdataEscape(bool on)
XmlCdataEscape (escape "]]>")
virtual const std::string & Name(void) const
Get objects's name (reimplementing base faudes::Type)
LineIterator LinesEnd()
Access to line records by iterator.
virtual void XmlTextEscape(bool on)
XmlTextEscape (escape "<", ">", "&", "\"" and "'")
virtual void MuteComments(bool on)
Mute comments (convenience support for derived classes)
std::map< std::string, ActionAddress >::iterator ActionAddressIterator
Access to action record by iterator.
std::string RecentComment(void)
Recent muted comment (convenience support for derived classes)
virtual void IndentInc()
Indentation (convenience support for derived classes)
LineIterator LinesBegin()
Access to line records by iterator.
int mIntegerSize
compressed boolean capacity of target type integer
virtual std::ostream & Output(void)
Output stream.
std::map< std::string, LineAddress >::iterator LineIterator
Access to line records by iterator.
virtual void MuteVspace(bool on)
Mute empty lines (convenience support for derived classes)
static std::string VersionString(void)
Version (refers to macro COMPILEDES_VERSION, defined in cgp_codegenerator.h)
Idx Size(void) const
Number of generators.
virtual void IndentDec()
Indentation (convenience support for derived classes)
ActionAddressIterator ActionAddressesEnd()
Access to action addresses by iterator.
ActionAddressIterator ActionAddressesBegin()
Access to action addresses by iterator.
std::string mName
faudes object name (aka project name)
Abstract address; see also Absstract_Addresses.
virtual void DeclareSmallCarray(void)
Declare bit-mask loop-ups.
virtual void DoGenerateResetCode(void)
cut-and-paste template for code snippet assembly
virtual void DeclareReset(void)
Declare "reset".
virtual void DeclareStatus(void)
Declare "status".
std::string mLiteralPrepend
extra code to prepend
virtual void DeclareRecentEvent(void)
Declare "recent_event".
virtual void DeclareAux(void)
Declare variables local to the provided snippets, e.g. helpers for bit-mask computation.
bool mEventNameLookup
code option: event name lookup
virtual void DeclareEventNameLookup(void)
Declare symbolic name lookup tables.
std::map< std::string, bitarray_rec > mBitarrays
Record of all declared bit-arrays.
bool mStateNameLookup
code option: state name lookup
virtual void DeclareParallelState(void)
Declare "parallel_state".
std::string mIntegerType
target data type for integer
virtual void DeclareLoopState(void)
Declare loop state, i.e. line levels, loop flag.
virtual void DoGenerateCyclicCode(void)
cut-and-paste template for code snippet assembly
std::string mWordType
target data type for word
virtual void DeclareLargeCarray(void)
Declare compiled transition relations.
virtual void DeclareStateNameLookup(void)
Declare symbolic name lookup tables.
std::string mLiteralAppend
extra code to prepend
std::vector< bool > mHasStateNames
record per generator whether there is a lookup table
virtual void DeclarePendingEvents(void)
Declare "pending_events" and "enabled_events".
std::string mPrefix
universal prefix (pseudo name space)
Implementation of primitives by IEC 61131 ST.
virtual void DoReadTargetConfiguration(TokenReader &rTr)
File i/o.
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
File i/o.
virtual void Clear(void)
Clear all data.
virtual void DeclareSystime(void)
generate code: conditionals
virtual AX StringConstant(const std::string &val)
generate code: conditionals
virtual void Comment(const std::string &text)
generate code: conditionals
virtual AX IntegerConstant(int val)
generate code: conditionals
virtual void DecrementTimers(void)
code snippet
std::string mLiteralCyclic
option: extra cyclic code
virtual void DeclareImportSymbolicIo(void)
generate code: conditionals
virtual std::string TargetAddress(const AA &address)
abstract address conversion
virtual int CountImportPhysicalIo(void)
generate code: conditionals
virtual void DeclareTimers(void)
generate code: conditionals
bool mHasIecTimeOperators
option: overloaded operators for time maths
virtual AX WordConstant(word_t val)
generate code: conditionals
virtual int CountImportSymbolicIo(void)
generate code: conditionals
std::string mIecDeclarePhysical
option: formal declaration of io lines
virtual void LiteralCyclic(void)
generate code: conditionals
Target PlcOpen XML (IEC 61131-3 ST)
Definition cgp_plcoxml.h:91
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
File i/o.
virtual void WordarrayDeclare(const AA &address, int offset, int len)
generate code: conditionals
std::string mIecSchemeVersion
option: plcopen-xml version "v1.01" or "v2.01"
void DoGenerate(void)
code generation hook (overall)
std::string mIecToolVendor
option: xml entry file header "company"
void DoGenerateInterface(void)
code generation (cyclic function, interface)
PlcoxmlCodeGenerator(void)
Constructor.
std::string mIecContentAuthor
option: xml entry content header "author"
virtual void DeclareImportPhysicalIo(void)
generate code: conditionals
std::string mIecContentOrganization
option: xml entry content header "company"
void DoGenerateBody(void)
code generation (cyclicg function, st body)
virtual ~PlcoxmlCodeGenerator(void)
Explicit destructor.
virtual void Clear(void)
Clear all data.
void DoGenerateFunction(void)
code generation hook (cyclic function)
virtual void IntarrayDeclare(const AA &address, int offset, int len)
generate code: conditionals
void DoGenerateLookups(void)
code generation hook (symbolic name lookup functions)
std::string mIecTextElement
option: plain text xml-element "cdata", "xhtml", or "pre"
virtual void CintarrayDeclare(const AA &address, int offset, const std::vector< int > &val)
generate code: conditionals
virtual void DoReadTargetConfiguration(TokenReader &rTr)
File i/o.
std::string mIecContentVersion
option: xml entry content header "version"
virtual void CwordarrayDeclare(const AA &address, int offset, const std::vector< word_t > &val)
generate code: conditionals
virtual void VariableDeclare(const std::string &ladd, const std::string &ltype)
generate code: conditionals
virtual void CstrarrayDeclare(const AA &address, int offset, const std::vector< std::string > &val)
generate code: conditionals